Annotation of embedaddon/php/main/output.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
                      5:    | Copyright (c) 1997-2012 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:    | Authors: Zeev Suraski <zeev@zend.com>                                |
                     16:    |          Thies C. Arntzen <thies@thieso.net>                         |
                     17:    |          Marcus Boerger <helly@php.net>                              |
                     18:    +----------------------------------------------------------------------+
                     19: */
                     20: 
                     21: /* $Id: output.c 321634 2012-01-01 13:15:04Z felipe $ */
                     22: 
                     23: #include "php.h"
                     24: #include "ext/standard/head.h"
                     25: #include "ext/standard/basic_functions.h"
                     26: #include "ext/standard/url_scanner_ex.h"
                     27: #if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
                     28: #include "ext/zlib/php_zlib.h"
                     29: #endif
                     30: #include "SAPI.h"
                     31: 
                     32: #define OB_DEFAULT_HANDLER_NAME "default output handler"
                     33: 
                     34: /* output functions */
                     35: static int php_b_body_write(const char *str, uint str_length TSRMLS_DC);
                     36: 
                     37: static int php_ob_init(uint initial_size, uint block_size, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC);
                     38: static void php_ob_append(const char *text, uint text_length TSRMLS_DC);
                     39: #if 0
                     40: static void php_ob_prepend(const char *text, uint text_length);
                     41: #endif
                     42: 
                     43: #ifdef ZTS
                     44: int output_globals_id;
                     45: #else
                     46: php_output_globals output_globals;
                     47: #endif
                     48: 
                     49: /* {{{ php_default_output_func */
                     50: PHPAPI int php_default_output_func(const char *str, uint str_len TSRMLS_DC)
                     51: {
                     52:        fwrite(str, 1, str_len, stderr);
                     53: /* See http://support.microsoft.com/kb/190351 */
                     54: #ifdef PHP_WIN32
                     55:        fflush(stderr);
                     56: #endif
                     57:        return str_len;
                     58: }
                     59: /* }}} */
                     60: 
                     61: /* {{{ php_output_init_globals */
                     62: static void php_output_init_globals(php_output_globals *output_globals_p TSRMLS_DC)
                     63: {
                     64:        OG(php_body_write) = php_default_output_func;
                     65:        OG(php_header_write) = php_default_output_func;
                     66:        OG(implicit_flush) = 0;
                     67:        OG(output_start_filename) = NULL;
                     68:        OG(output_start_lineno) = 0;
                     69: }
                     70: /* }}} */
                     71: 
                     72: /* {{{ php_output_startup
                     73:  * Start output layer */
                     74: PHPAPI void php_output_startup(void)
                     75: {
                     76: #ifdef ZTS
                     77:        ts_allocate_id(&output_globals_id, sizeof(php_output_globals), (ts_allocate_ctor) php_output_init_globals, NULL);
                     78: #else
                     79:        php_output_init_globals(&output_globals TSRMLS_CC);
                     80: #endif
                     81: }
                     82: /* }}} */
                     83: 
                     84: /* {{{ php_output_activate
                     85:  * Initilize output global for activation */
                     86: PHPAPI void php_output_activate(TSRMLS_D)
                     87: {
                     88:        OG(php_body_write) = php_ub_body_write;
                     89:        OG(php_header_write) = sapi_module.ub_write;
                     90:        OG(ob_nesting_level) = 0;
                     91:        OG(ob_lock) = 0;
                     92:        OG(disable_output) = 0;
                     93:        OG(output_start_filename) = NULL;
                     94:        OG(output_start_lineno) = 0;
                     95: }
                     96: /* }}} */
                     97: 
                     98: /* {{{ php_output_register_constants */
                     99: void php_output_register_constants(TSRMLS_D)
                    100: {
                    101:        REGISTER_MAIN_LONG_CONSTANT("PHP_OUTPUT_HANDLER_START", PHP_OUTPUT_HANDLER_START, CONST_CS | CONST_PERSISTENT);
                    102:        REGISTER_MAIN_LONG_CONSTANT("PHP_OUTPUT_HANDLER_CONT", PHP_OUTPUT_HANDLER_CONT, CONST_CS | CONST_PERSISTENT);
                    103:        REGISTER_MAIN_LONG_CONSTANT("PHP_OUTPUT_HANDLER_END", PHP_OUTPUT_HANDLER_END, CONST_CS | CONST_PERSISTENT);
                    104: }
                    105: /* }}} */
                    106: 
                    107: /* {{{ php_output_set_status
                    108:  * Toggle output status.  Do NOT use in application code, only in SAPIs where appropriate. */
                    109: PHPAPI void php_output_set_status(zend_bool status TSRMLS_DC)
                    110: {
                    111:        OG(disable_output) = !status;
                    112: }
                    113: /* }}} */
                    114: 
                    115: /* {{{ php_body_write
                    116:  * Write body part */
                    117: PHPAPI int php_body_write(const char *str, uint str_length TSRMLS_DC)
                    118: {
                    119:        return OG(php_body_write)(str, str_length TSRMLS_CC);
                    120: }
                    121: /* }}} */
                    122: 
                    123: /* {{{ php_header_write
                    124:  * Write HTTP header */
                    125: PHPAPI int php_header_write(const char *str, uint str_length TSRMLS_DC)
                    126: {
                    127:        if (OG(disable_output)) {
                    128:                return 0;
                    129:        } else {
                    130:                return OG(php_header_write)(str, str_length TSRMLS_CC);
                    131:        }
                    132: }
                    133: /* }}} */
                    134: 
                    135: /* {{{ php_start_ob_buffer
                    136:  * Start output buffering */
                    137: PHPAPI int php_start_ob_buffer(zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC)
                    138: {
                    139:        uint initial_size, block_size;
                    140: 
                    141:        if (OG(ob_lock)) {
                    142:                if (SG(headers_sent) && !SG(request_info).headers_only) {
                    143:                        OG(php_body_write) = php_ub_body_write_no_header;
                    144:                } else {
                    145:                        OG(php_body_write) = php_ub_body_write;
                    146:                }
                    147:                OG(ob_nesting_level) = 0;
                    148:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_ERROR, "Cannot use output buffering in output buffering display handlers");
                    149:                return FAILURE;
                    150:        }
                    151:        if (chunk_size > 0) {
                    152:                if (chunk_size==1) {
                    153:                        chunk_size = 4096;
                    154:                }
                    155:                initial_size = (chunk_size*3/2);
                    156:                block_size = chunk_size/2;
                    157:        } else {
                    158:                initial_size = 40*1024;
                    159:                block_size = 10*1024;
                    160:        }
                    161:        return php_ob_init(initial_size, block_size, output_handler, chunk_size, erase TSRMLS_CC);
                    162: }
                    163: /* }}} */
                    164: 
                    165: /* {{{ php_start_ob_buffer_named
                    166:  * Start output buffering */
                    167: PHPAPI int php_start_ob_buffer_named(const char *output_handler_name, uint chunk_size, zend_bool erase TSRMLS_DC)
                    168: {
                    169:        zval *output_handler;
                    170:        int result;
                    171: 
                    172:        ALLOC_INIT_ZVAL(output_handler);
                    173:        Z_STRLEN_P(output_handler) = strlen(output_handler_name);       /* this can be optimized */
                    174:        Z_STRVAL_P(output_handler) = estrndup(output_handler_name, Z_STRLEN_P(output_handler));
                    175:        Z_TYPE_P(output_handler) = IS_STRING;
                    176:        result = php_start_ob_buffer(output_handler, chunk_size, erase TSRMLS_CC);
                    177:        zval_dtor(output_handler);
                    178:        FREE_ZVAL(output_handler);
                    179:        return result;
                    180: }
                    181: /* }}} */
                    182: 
                    183: /* {{{ php_end_ob_buffer
                    184:  * End output buffering (one level) */
                    185: PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush TSRMLS_DC)
                    186: {
                    187:        char *final_buffer=NULL;
                    188:        unsigned int final_buffer_length=0;
                    189:        zval *alternate_buffer=NULL;
                    190:        char *to_be_destroyed_buffer, *to_be_destroyed_handler_name;
                    191:        char *to_be_destroyed_handled_output[2] = { 0, 0 };
                    192:        int status;
                    193:        php_ob_buffer *prev_ob_buffer_p=NULL;
                    194:        php_ob_buffer orig_ob_buffer;
                    195: 
                    196:        if (OG(ob_nesting_level)==0) {
                    197:                return;
                    198:        }
                    199:        status = 0;
                    200:        if (!OG(active_ob_buffer).status & PHP_OUTPUT_HANDLER_START) {
                    201:                /* our first call */
                    202:                status |= PHP_OUTPUT_HANDLER_START;
                    203:        }
                    204:        if (just_flush) {
                    205:                status |= PHP_OUTPUT_HANDLER_CONT;
                    206:        } else {
                    207:                status |= PHP_OUTPUT_HANDLER_END;
                    208:        }
                    209: 
                    210: #if 0
                    211:  {
                    212:         FILE *fp;
                    213:         fp = fopen("/tmp/ob_log", "a");
                    214:         fprintf(fp, "NestLevel: %d  ObStatus: %d  HandlerName: %s\n", OG(ob_nesting_level), status, OG(active_ob_buffer).handler_name);
                    215:         fclose(fp);
                    216:  }
                    217: #endif
                    218: 
                    219:        if (OG(active_ob_buffer).internal_output_handler) {
                    220:                final_buffer = OG(active_ob_buffer).internal_output_handler_buffer;
                    221:                final_buffer_length = OG(active_ob_buffer).internal_output_handler_buffer_size;
                    222:                OG(active_ob_buffer).internal_output_handler(OG(active_ob_buffer).buffer, OG(active_ob_buffer).text_length, &final_buffer, &final_buffer_length, status TSRMLS_CC);
                    223:        } else if (OG(active_ob_buffer).output_handler) {
                    224:                zval **params[2];
                    225:                zval *orig_buffer;
                    226:                zval *z_status;
                    227: 
                    228:                ALLOC_INIT_ZVAL(orig_buffer);
                    229:                ZVAL_STRINGL(orig_buffer, OG(active_ob_buffer).buffer, OG(active_ob_buffer).text_length, 1);
                    230: 
                    231:                ALLOC_INIT_ZVAL(z_status);
                    232:                ZVAL_LONG(z_status, status);
                    233: 
                    234:                params[0] = &orig_buffer;
                    235:                params[1] = &z_status;
                    236:                OG(ob_lock) = 1;
                    237: 
                    238:                if (call_user_function_ex(CG(function_table), NULL, OG(active_ob_buffer).output_handler, &alternate_buffer, 2, params, 1, NULL TSRMLS_CC)==SUCCESS) {
                    239:                        if (alternate_buffer && !(Z_TYPE_P(alternate_buffer)==IS_BOOL && Z_BVAL_P(alternate_buffer)==0)) {
                    240:                                convert_to_string_ex(&alternate_buffer);
                    241:                                final_buffer = Z_STRVAL_P(alternate_buffer);
                    242:                                final_buffer_length = Z_STRLEN_P(alternate_buffer);
                    243:                        }
                    244:                }
                    245:                OG(ob_lock) = 0;
                    246:                if (!just_flush) {
                    247:                        zval_ptr_dtor(&OG(active_ob_buffer).output_handler);
                    248:                }
                    249:                zval_ptr_dtor(&orig_buffer);
                    250:                zval_ptr_dtor(&z_status);
                    251:        }
                    252: 
                    253:        if (!final_buffer) {
                    254:                final_buffer = OG(active_ob_buffer).buffer;
                    255:                final_buffer_length = OG(active_ob_buffer).text_length;
                    256:        }
                    257: 
                    258:        if (OG(ob_nesting_level)==1) { /* end buffering */
                    259:                if (SG(headers_sent) && !SG(request_info).headers_only) {
                    260:                        OG(php_body_write) = php_ub_body_write_no_header;
                    261:                } else {
                    262:                        OG(php_body_write) = php_ub_body_write;
                    263:                }
                    264:        }
                    265: 
                    266:        to_be_destroyed_buffer = OG(active_ob_buffer).buffer;
                    267:        to_be_destroyed_handler_name = OG(active_ob_buffer).handler_name;
                    268:        if (OG(active_ob_buffer).internal_output_handler
                    269:                && (final_buffer != OG(active_ob_buffer).internal_output_handler_buffer)
                    270:                && (final_buffer != OG(active_ob_buffer).buffer)) {
                    271:                to_be_destroyed_handled_output[0] = final_buffer;
                    272:        }
                    273: 
                    274:        if (!just_flush) {
                    275:                if (OG(active_ob_buffer).internal_output_handler) {
                    276:                        to_be_destroyed_handled_output[1] = OG(active_ob_buffer).internal_output_handler_buffer;
                    277:                }
                    278:        }
                    279:        if (OG(ob_nesting_level)>1) { /* restore previous buffer */
                    280:                zend_stack_top(&OG(ob_buffers), (void **) &prev_ob_buffer_p);
                    281:                orig_ob_buffer = OG(active_ob_buffer);
                    282:                OG(active_ob_buffer) = *prev_ob_buffer_p;
                    283:                zend_stack_del_top(&OG(ob_buffers));
                    284:                if (!just_flush && OG(ob_nesting_level)==2) { /* destroy the stack */
                    285:                        zend_stack_destroy(&OG(ob_buffers));
                    286:                }
                    287:        }
                    288:        OG(ob_nesting_level)--;
                    289: 
                    290:        if (send_buffer) {
                    291:                if (just_flush) { /* if flush is called prior to proper end, ensure presence of NUL */
                    292:                        final_buffer[final_buffer_length] = '\0';
                    293:                }
                    294:                OG(php_body_write)(final_buffer, final_buffer_length TSRMLS_CC);
                    295:        }
                    296: 
                    297:        if (just_flush) { /* we restored the previous ob, return to the current */
                    298:                if (prev_ob_buffer_p) {
                    299:                        zend_stack_push(&OG(ob_buffers), &OG(active_ob_buffer), sizeof(php_ob_buffer));
                    300:                        OG(active_ob_buffer) = orig_ob_buffer;
                    301:                }
                    302:                OG(ob_nesting_level)++;
                    303:        }
                    304: 
                    305:        if (alternate_buffer) {
                    306:                zval_ptr_dtor(&alternate_buffer);
                    307:        }
                    308: 
                    309:        if (status & PHP_OUTPUT_HANDLER_END) {
                    310:                efree(to_be_destroyed_handler_name);
                    311:        }
                    312:        if (!just_flush) {
                    313:                efree(to_be_destroyed_buffer);
                    314:        } else {
                    315:                OG(active_ob_buffer).text_length = 0;
                    316:                OG(active_ob_buffer).status |= PHP_OUTPUT_HANDLER_START;
                    317:                OG(php_body_write) = php_b_body_write;
                    318:        }
                    319:        if (to_be_destroyed_handled_output[0]) {
                    320:                efree(to_be_destroyed_handled_output[0]);
                    321:        }
                    322:        if (to_be_destroyed_handled_output[1]) {
                    323:                efree(to_be_destroyed_handled_output[1]);
                    324:        }
                    325: }
                    326: /* }}} */
                    327: 
                    328: /* {{{ php_end_ob_buffers
                    329:  * End output buffering (all buffers) */
                    330: PHPAPI void php_end_ob_buffers(zend_bool send_buffer TSRMLS_DC)
                    331: {
                    332:        while (OG(ob_nesting_level)!=0) {
                    333:                php_end_ob_buffer(send_buffer, 0 TSRMLS_CC);
                    334:        }
                    335: }
                    336: /* }}} */
                    337: 
                    338: /* {{{ php_start_implicit_flush
                    339:  */
                    340: PHPAPI void php_start_implicit_flush(TSRMLS_D)
                    341: {
                    342:        OG(implicit_flush) = 1;
                    343: }
                    344: /* }}} */
                    345: 
                    346: /* {{{ php_end_implicit_flush
                    347:  */
                    348: PHPAPI void php_end_implicit_flush(TSRMLS_D)
                    349: {
                    350:        OG(implicit_flush) = 0;
                    351: }
                    352: /* }}} */
                    353: 
                    354: /* {{{ char *php_get_output_start_filename(TSRMLS_D)
                    355:  *  Return filename start output something */
                    356: PHPAPI char *php_get_output_start_filename(TSRMLS_D)
                    357: {
                    358:        return OG(output_start_filename);
                    359: }
                    360: /* }}} */
                    361: 
                    362: /* {{{ char *php_get_output_start_lineno(TSRMLS_D)
                    363:  * Return line number start output something */
                    364: PHPAPI int php_get_output_start_lineno(TSRMLS_D)
                    365: {
                    366:        return OG(output_start_lineno);
                    367: }
                    368: /* }}} */
                    369: 
                    370: /* {{{ php_ob_set_internal_handler
                    371:  */
                    372: PHPAPI void php_ob_set_internal_handler(php_output_handler_func_t internal_output_handler, uint buffer_size, char *handler_name, zend_bool erase TSRMLS_DC)
                    373: {
                    374:        if (OG(ob_nesting_level) == 0 || OG(active_ob_buffer).internal_output_handler || strcmp(OG(active_ob_buffer).handler_name, OB_DEFAULT_HANDLER_NAME)) {
                    375:                php_start_ob_buffer(NULL, buffer_size, erase TSRMLS_CC);
                    376:        }
                    377: 
                    378:        OG(active_ob_buffer).internal_output_handler = internal_output_handler;
                    379:        OG(active_ob_buffer).internal_output_handler_buffer = (char *) emalloc(buffer_size);
                    380:        OG(active_ob_buffer).internal_output_handler_buffer_size = buffer_size;
                    381:        if (OG(active_ob_buffer).handler_name) {
                    382:                efree(OG(active_ob_buffer).handler_name);
                    383:        }
                    384:        OG(active_ob_buffer).handler_name = estrdup(handler_name);
                    385:        OG(active_ob_buffer).erase = erase;
                    386: }
                    387: /* }}} */
                    388: 
                    389: /*
                    390:  * Output buffering - implementation
                    391:  */
                    392: 
                    393: /* {{{ php_ob_allocate
                    394:  */
                    395: static inline void php_ob_allocate(uint text_length TSRMLS_DC)
                    396: {
                    397:        uint new_len = OG(active_ob_buffer).text_length + text_length;
                    398: 
                    399:        if (OG(active_ob_buffer).size < new_len) {
                    400:                uint buf_size = OG(active_ob_buffer).size;
                    401:                while (buf_size <= new_len) {
                    402:                        buf_size += OG(active_ob_buffer).block_size;
                    403:                }
                    404: 
                    405:                OG(active_ob_buffer).buffer = (char *) erealloc(OG(active_ob_buffer).buffer, buf_size+1);
                    406:                OG(active_ob_buffer).size = buf_size;
                    407:        }
                    408:        OG(active_ob_buffer).text_length = new_len;
                    409: }
                    410: /* }}} */
                    411: 
                    412: /* {{{ php_ob_init_conflict
                    413:  * Returns 1 if handler_set is already used and generates error message */
                    414: PHPAPI int php_ob_init_conflict(char *handler_new, char *handler_set TSRMLS_DC)
                    415: {
                    416:        if (php_ob_handler_used(handler_set TSRMLS_CC)) {
                    417:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_WARNING, "output handler '%s' conflicts with '%s'", handler_new, handler_set);
                    418:                return 1;
                    419:        }
                    420:        return 0;
                    421: }
                    422: /* }}} */
                    423: 
                    424: /* {{{ php_ob_init_named
                    425:  */
                    426: static int php_ob_init_named(uint initial_size, uint block_size, char *handler_name, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC)
                    427: {
                    428:        php_ob_buffer tmp_buf;
                    429: 
                    430:        if (output_handler && !zend_is_callable(output_handler, 0, NULL TSRMLS_CC)) {
                    431:                return FAILURE;
                    432:        }
                    433: 
                    434:        tmp_buf.block_size = block_size;
                    435:        tmp_buf.size = initial_size;
                    436:        tmp_buf.buffer = (char *) emalloc(initial_size+1);
                    437:        tmp_buf.text_length = 0;
                    438:        tmp_buf.output_handler = output_handler;
                    439:        tmp_buf.chunk_size = chunk_size;
                    440:        tmp_buf.status = 0;
                    441:        tmp_buf.internal_output_handler = NULL;
                    442:        tmp_buf.internal_output_handler_buffer = NULL;
                    443:        tmp_buf.internal_output_handler_buffer_size = 0;
                    444:        tmp_buf.handler_name = estrdup(handler_name&&handler_name[0]?handler_name:OB_DEFAULT_HANDLER_NAME);
                    445:        tmp_buf.erase = erase;
                    446: 
                    447:        if (OG(ob_nesting_level)>0) {
                    448: #if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
                    449:                if (!strncmp(handler_name, "ob_gzhandler", sizeof("ob_gzhandler")) && php_ob_gzhandler_check(TSRMLS_C)) {
                    450:                        return FAILURE;
                    451:                }
                    452: #endif
                    453:                if (OG(ob_nesting_level)==1) { /* initialize stack */
                    454:                        zend_stack_init(&OG(ob_buffers));
                    455:                }
                    456:                zend_stack_push(&OG(ob_buffers), &OG(active_ob_buffer), sizeof(php_ob_buffer));
                    457:        }
                    458:        OG(ob_nesting_level)++;
                    459:        OG(active_ob_buffer) = tmp_buf;
                    460:        OG(php_body_write) = php_b_body_write;
                    461:        return SUCCESS;
                    462: }
                    463: /* }}} */
                    464: 
                    465: /* {{{ php_ob_handler_from_string
                    466:  * Create zval output handler from string */
                    467: static zval* php_ob_handler_from_string(const char *handler_name, int len TSRMLS_DC)
                    468: {
                    469:        zval *output_handler;
                    470: 
                    471:        ALLOC_INIT_ZVAL(output_handler);
                    472:        Z_STRLEN_P(output_handler) = len;
                    473:        Z_STRVAL_P(output_handler) = estrndup(handler_name, len);
                    474:        Z_TYPE_P(output_handler) = IS_STRING;
                    475:        return output_handler;
                    476: }
                    477: /* }}} */
                    478: 
                    479: /* {{{ php_ob_init
                    480:  */
                    481: static int php_ob_init(uint initial_size, uint block_size, zval *output_handler, uint chunk_size, zend_bool erase TSRMLS_DC)
                    482: {
                    483:        int result = FAILURE, handler_len, len;
                    484:        char *handler_name, *next_handler_name;
                    485:        HashPosition pos;
                    486:        zval **tmp;
                    487:        zval *handler_zval;
                    488: 
                    489:        if (output_handler && output_handler->type == IS_STRING) {
                    490:                handler_name = Z_STRVAL_P(output_handler);
                    491:                handler_len  = Z_STRLEN_P(output_handler);
                    492: 
                    493:                result = SUCCESS;
                    494:                if (handler_len && handler_name[0] != '\0') {
                    495:                        while ((next_handler_name=strchr(handler_name, ',')) != NULL) {
                    496:                                len = next_handler_name-handler_name;
                    497:                                next_handler_name = estrndup(handler_name, len);
                    498:                                handler_zval = php_ob_handler_from_string(next_handler_name, len TSRMLS_CC);
                    499:                                result = php_ob_init_named(initial_size, block_size, next_handler_name, handler_zval, chunk_size, erase TSRMLS_CC);
                    500:                                if (result != SUCCESS) {
                    501:                                        zval_dtor(handler_zval);
                    502:                                        FREE_ZVAL(handler_zval);
                    503:                                }
                    504:                                handler_name += len+1;
                    505:                                handler_len -= len+1;
                    506:                                efree(next_handler_name);
                    507:                        }
                    508:                }
                    509:                if (result == SUCCESS) {
                    510:                        handler_zval = php_ob_handler_from_string(handler_name, handler_len TSRMLS_CC);
                    511:                        result = php_ob_init_named(initial_size, block_size, handler_name, handler_zval, chunk_size, erase TSRMLS_CC);
                    512:                        if (result != SUCCESS) {
                    513:                                zval_dtor(handler_zval);
                    514:                                FREE_ZVAL(handler_zval);
                    515:                        }
                    516:                }
                    517:        } else if (output_handler && output_handler->type == IS_ARRAY) {
                    518:                /* do we have array(object,method) */
                    519:                if (zend_is_callable(output_handler, 0, &handler_name TSRMLS_CC)) {
                    520:                        SEPARATE_ZVAL(&output_handler);
                    521:                        Z_ADDREF_P(output_handler);
                    522:                        result = php_ob_init_named(initial_size, block_size, handler_name, output_handler, chunk_size, erase TSRMLS_CC);
                    523:                        efree(handler_name);
                    524:                } else {
                    525:                        efree(handler_name);
                    526:                        /* init all array elements recursively */
                    527:                        zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(output_handler), &pos);
                    528:                        while (zend_hash_get_current_data_ex(Z_ARRVAL_P(output_handler), (void **)&tmp, &pos) == SUCCESS) {
                    529:                                result = php_ob_init(initial_size, block_size, *tmp, chunk_size, erase TSRMLS_CC);
                    530:                                if (result == FAILURE) {
                    531:                                        break;
                    532:                                }
                    533:                                zend_hash_move_forward_ex(Z_ARRVAL_P(output_handler), &pos);
                    534:                        }
                    535:                }
                    536:        } else if (output_handler && output_handler->type == IS_OBJECT) {
                    537:                /* do we have callable object */
                    538:                if (zend_is_callable(output_handler, 0, &handler_name TSRMLS_CC)) {
                    539:                        SEPARATE_ZVAL(&output_handler);
                    540:                        Z_ADDREF_P(output_handler);
                    541:                        result = php_ob_init_named(initial_size, block_size, handler_name, output_handler, chunk_size, erase TSRMLS_CC);
                    542:                        efree(handler_name);
                    543:                } else {
                    544:                        efree(handler_name);
                    545:                        php_error_docref(NULL TSRMLS_CC, E_ERROR, "No method name given: use ob_start(array($object,'method')) to specify instance $object and the name of a method of class %s to use as output handler", Z_OBJCE_P(output_handler)->name);
                    546:                        result = FAILURE;
                    547:                }
                    548:        } else {
                    549:                result = php_ob_init_named(initial_size, block_size, OB_DEFAULT_HANDLER_NAME, NULL, chunk_size, erase TSRMLS_CC);
                    550:        }
                    551:        return result;
                    552: }
                    553: /* }}} */
                    554: 
                    555: /* {{{ php_ob_list_each
                    556:  */
                    557: static int php_ob_list_each(php_ob_buffer *ob_buffer, zval *ob_handler_array)
                    558: {
                    559:        add_next_index_string(ob_handler_array, ob_buffer->handler_name, 1);
                    560:        return 0;
                    561: }
                    562: /* }}} */
                    563: 
                    564: /* {{{ php_ob_used_each
                    565:    Sets handler_name to NULL is found */
                    566: static int php_ob_handler_used_each(php_ob_buffer *ob_buffer, char **handler_name)
                    567: {
                    568:        if (!strcmp(ob_buffer->handler_name, *handler_name)) {
                    569:                *handler_name = NULL;
                    570:                return 1;
                    571:        }
                    572:        return 0;
                    573: }
                    574: /* }}} */
                    575: 
                    576: /* {{{ php_ob_used
                    577:    returns 1 if given handler_name is used as output_handler */
                    578: PHPAPI int php_ob_handler_used(char *handler_name TSRMLS_DC)
                    579: {
                    580:        char *tmp = handler_name;
                    581: 
                    582:        if (OG(ob_nesting_level)) {
                    583:                if (!strcmp(OG(active_ob_buffer).handler_name, handler_name)) {
                    584:                        return 1;
                    585:                }
                    586:                if (OG(ob_nesting_level)>1) {
                    587:                        zend_stack_apply_with_argument(&OG(ob_buffers), ZEND_STACK_APPLY_BOTTOMUP, (int (*)(void *element, void *)) php_ob_handler_used_each, &tmp);
                    588:                }
                    589:        }
                    590:        return tmp ? 0 : 1;
                    591: }
                    592: /* }}} */
                    593: 
                    594: /* {{{ php_ob_append
                    595:  */
                    596: static inline void php_ob_append(const char *text, uint text_length TSRMLS_DC)
                    597: {
                    598:        char *target;
                    599:        int original_ob_text_length;
                    600: 
                    601:        original_ob_text_length=OG(active_ob_buffer).text_length;
                    602: 
                    603:        php_ob_allocate(text_length TSRMLS_CC);
                    604:        target = OG(active_ob_buffer).buffer+original_ob_text_length;
                    605:        memcpy(target, text, text_length);
                    606:        target[text_length]=0;
                    607: 
                    608:        /* If implicit_flush is On or chunked buffering, send contents to next buffer and return. */
                    609:        if (OG(active_ob_buffer).chunk_size
                    610:                && OG(active_ob_buffer).text_length >= OG(active_ob_buffer).chunk_size) {
                    611: 
                    612:                php_end_ob_buffer(1, 1 TSRMLS_CC);
                    613:                return;
                    614:        }
                    615: }
                    616: /* }}} */
                    617: 
                    618: #if 0
                    619: static inline void php_ob_prepend(const char *text, uint text_length)
                    620: {
                    621:        char *p, *start;
                    622:        TSRMLS_FETCH();
                    623: 
                    624:        php_ob_allocate(text_length TSRMLS_CC);
                    625: 
                    626:        /* php_ob_allocate() may change OG(ob_buffer), so we can't initialize p&start earlier */
                    627:        p = OG(ob_buffer)+OG(ob_text_length);
                    628:        start = OG(ob_buffer);
                    629: 
                    630:        while (--p>=start) {
                    631:                p[text_length] = *p;
                    632:        }
                    633:        memcpy(OG(ob_buffer), text, text_length);
                    634:        OG(ob_buffer)[OG(active_ob_buffer).text_length]=0;
                    635: }
                    636: #endif
                    637: 
                    638: /* {{{ php_ob_get_buffer
                    639:  * Return the current output buffer */
                    640: PHPAPI int php_ob_get_buffer(zval *p TSRMLS_DC)
                    641: {
                    642:        if (OG(ob_nesting_level)==0) {
                    643:                return FAILURE;
                    644:        }
                    645:        ZVAL_STRINGL(p, OG(active_ob_buffer).buffer, OG(active_ob_buffer).text_length, 1);
                    646:        return SUCCESS;
                    647: }
                    648: /* }}} */
                    649: 
                    650: /* {{{ php_ob_get_length
                    651:  * Return the size of the current output buffer */
                    652: PHPAPI int php_ob_get_length(zval *p TSRMLS_DC)
                    653: {
                    654:        if (OG(ob_nesting_level) == 0) {
                    655:                return FAILURE;
                    656:        }
                    657:        ZVAL_LONG(p, OG(active_ob_buffer).text_length);
                    658:        return SUCCESS;
                    659: }
                    660: /* }}} */
                    661: 
                    662: /*
                    663:  * Wrapper functions - implementation
                    664:  */
                    665: 
                    666: /* buffered output function */
                    667: static int php_b_body_write(const char *str, uint str_length TSRMLS_DC)
                    668: {
                    669:        php_ob_append(str, str_length TSRMLS_CC);
                    670:        return str_length;
                    671: }
                    672: 
                    673: /* {{{ php_ub_body_write_no_header
                    674:  */
                    675: PHPAPI int php_ub_body_write_no_header(const char *str, uint str_length TSRMLS_DC)
                    676: {
                    677:        int result;
                    678: 
                    679:        if (OG(disable_output)) {
                    680:                return 0;
                    681:        }
                    682: 
                    683:        result = OG(php_header_write)(str, str_length TSRMLS_CC);
                    684: 
                    685:        if (OG(implicit_flush)) {
                    686:                sapi_flush(TSRMLS_C);
                    687:        }
                    688: 
                    689:        return result;
                    690: }
                    691: /* }}} */
                    692: 
                    693: /* {{{ php_ub_body_write
                    694:  */
                    695: PHPAPI int php_ub_body_write(const char *str, uint str_length TSRMLS_DC)
                    696: {
                    697:        int result = 0;
                    698: 
                    699:        if (SG(request_info).headers_only) {
                    700:                if(SG(headers_sent)) {
                    701:                        return 0;
                    702:                }
                    703:                php_header(TSRMLS_C);
                    704:                zend_bailout();
                    705:        }
                    706:        if (php_header(TSRMLS_C)) {
                    707:                if (zend_is_compiling(TSRMLS_C)) {
                    708:                        OG(output_start_filename) = zend_get_compiled_filename(TSRMLS_C);
                    709:                        OG(output_start_lineno) = zend_get_compiled_lineno(TSRMLS_C);
                    710:                } else if (zend_is_executing(TSRMLS_C)) {
                    711:                        OG(output_start_filename) = zend_get_executed_filename(TSRMLS_C);
                    712:                        OG(output_start_lineno) = zend_get_executed_lineno(TSRMLS_C);
                    713:                }
                    714: 
                    715:                OG(php_body_write) = php_ub_body_write_no_header;
                    716:                result = php_ub_body_write_no_header(str, str_length TSRMLS_CC);
                    717:        }
                    718: 
                    719:        return result;
                    720: }
                    721: /* }}} */
                    722: 
                    723: /* {{{ int php_ob_buffer_status(php_ob_buffer *ob_buffer, zval *result)
                    724:  */
                    725: static int php_ob_buffer_status(php_ob_buffer *ob_buffer, zval *result)
                    726: {
                    727:        zval *elem;
                    728: 
                    729:        MAKE_STD_ZVAL(elem);
                    730:        array_init(elem);
                    731: 
                    732:        add_assoc_long(elem, "chunk_size", ob_buffer->chunk_size);
                    733:        if (!ob_buffer->chunk_size) {
                    734:                add_assoc_long(elem, "size", ob_buffer->size);
                    735:                add_assoc_long(elem, "block_size", ob_buffer->block_size);
                    736:        }
                    737:        if (ob_buffer->internal_output_handler) {
                    738:                add_assoc_long(elem, "type", PHP_OUTPUT_HANDLER_INTERNAL);
                    739:                add_assoc_long(elem, "buffer_size", ob_buffer->internal_output_handler_buffer_size);
                    740:        } else {
                    741:                add_assoc_long(elem, "type", PHP_OUTPUT_HANDLER_USER);
                    742:        }
                    743:        add_assoc_long(elem, "status", ob_buffer->status);
                    744:        add_assoc_string(elem, "name", ob_buffer->handler_name, 1);
                    745:        add_assoc_bool(elem, "del", ob_buffer->erase);
                    746:        add_next_index_zval(result, elem);
                    747: 
                    748:        return SUCCESS;
                    749: }
                    750: /* }}} */
                    751: 
                    752: /*
                    753:  * USERLAND (nearly 1:1 of old output.c)
                    754:  */
                    755: 
                    756: /* {{{ proto bool ob_start([string|array user_function [, int chunk_size [, bool erase]]])
                    757:    Turn on Output Buffering (specifying an optional output handler). */
                    758: PHP_FUNCTION(ob_start)
                    759: {
                    760:        zval *output_handler = NULL;
                    761:        long chunk_size = 0;
                    762:        zend_bool erase = 1;
                    763: 
                    764:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z/lb", &output_handler, &chunk_size, &erase) == FAILURE) {
                    765:                return;
                    766:        }
                    767: 
                    768:        if (chunk_size < 0) {
                    769:                chunk_size = 0;
                    770:        }
                    771: 
                    772:        if (php_start_ob_buffer(output_handler, chunk_size, erase TSRMLS_CC) == FAILURE) {
                    773:                RETURN_FALSE;
                    774:        }
                    775:        RETURN_TRUE;
                    776: }
                    777: /* }}} */
                    778: 
                    779: /* {{{ proto bool ob_flush(void)
                    780:    Flush (send) contents of the output buffer. The last buffer content is sent to next buffer */
                    781: PHP_FUNCTION(ob_flush)
                    782: {
                    783:        if (zend_parse_parameters_none() == FAILURE) {
                    784:                return;
                    785:        }
                    786: 
                    787:        if (!OG(ob_nesting_level)) {
                    788:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to flush buffer. No buffer to flush");
                    789:                RETURN_FALSE;
                    790:        }
                    791: 
                    792:        if (!OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) {
                    793:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to flush buffer %s", OG(active_ob_buffer).handler_name);
                    794:                RETURN_FALSE;
                    795:        }
                    796: 
                    797:        php_end_ob_buffer(1, 1 TSRMLS_CC);
                    798:        RETURN_TRUE;
                    799: }
                    800: /* }}} */
                    801: 
                    802: /* {{{ proto bool ob_clean(void)
                    803:    Clean (delete) the current output buffer */
                    804: PHP_FUNCTION(ob_clean)
                    805: {
                    806:        if (zend_parse_parameters_none() == FAILURE) {
                    807:                return;
                    808:        }
                    809: 
                    810:        if (!OG(ob_nesting_level)) {
                    811:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete");
                    812:                RETURN_FALSE;
                    813:        }
                    814: 
                    815:        if (!OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) {
                    816:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s", OG(active_ob_buffer).handler_name);
                    817:                RETURN_FALSE;
                    818:        }
                    819: 
                    820:        php_end_ob_buffer(0, 1 TSRMLS_CC);
                    821:        RETURN_TRUE;
                    822: }
                    823: /* }}} */
                    824: 
                    825: /* {{{ proto bool ob_end_flush(void)
                    826:    Flush (send) the output buffer, and delete current output buffer */
                    827: PHP_FUNCTION(ob_end_flush)
                    828: {
                    829:        if (zend_parse_parameters_none() == FAILURE) {
                    830:                return;
                    831:        }
                    832: 
                    833:        if (!OG(ob_nesting_level)) {
                    834:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete and flush buffer. No buffer to delete or flush");
                    835:                RETURN_FALSE;
                    836:        }
                    837: 
                    838:        if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) {
                    839:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s", OG(active_ob_buffer).handler_name);
                    840:                RETURN_FALSE;
                    841:        }
                    842: 
                    843:        php_end_ob_buffer(1, 0 TSRMLS_CC);
                    844:        RETURN_TRUE;
                    845: }
                    846: /* }}} */
                    847: 
                    848: /* {{{ proto bool ob_end_clean(void)
                    849:    Clean the output buffer, and delete current output buffer */
                    850: PHP_FUNCTION(ob_end_clean)
                    851: {
                    852:        if (zend_parse_parameters_none() == FAILURE) {
                    853:                return;
                    854:        }
                    855: 
                    856:        if (!OG(ob_nesting_level)) {
                    857:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete");
                    858:                RETURN_FALSE;
                    859:        }
                    860: 
                    861:        if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) {
                    862:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s", OG(active_ob_buffer).handler_name);
                    863:                RETURN_FALSE;
                    864:        }
                    865: 
                    866:        php_end_ob_buffer(0, 0 TSRMLS_CC);
                    867:        RETURN_TRUE;
                    868: }
                    869: /* }}} */
                    870: 
                    871: /* {{{ proto bool ob_get_flush(void)
                    872:    Get current buffer contents, flush (send) the output buffer, and delete current output buffer */
                    873: PHP_FUNCTION(ob_get_flush)
                    874: {
                    875:        if (zend_parse_parameters_none() == FAILURE) {
                    876:                return;
                    877:        }
                    878: 
                    879:        if (php_ob_get_buffer(return_value TSRMLS_CC) == FAILURE) {
                    880:                RETURN_FALSE;
                    881:        }
                    882: 
                    883:        if (!OG(ob_nesting_level)) {
                    884:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete and flush buffer. No buffer to delete or flush");
                    885:                zval_dtor(return_value);
                    886:                RETURN_FALSE;
                    887:        }
                    888: 
                    889:        if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) {
                    890:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s", OG(active_ob_buffer).handler_name);
                    891:                zval_dtor(return_value);
                    892:                RETURN_FALSE;
                    893:        }
                    894: 
                    895:        php_end_ob_buffer(1, 0 TSRMLS_CC);
                    896: }
                    897: /* }}} */
                    898: 
                    899: /* {{{ proto bool ob_get_clean(void)
                    900:    Get current buffer contents and delete current output buffer */
                    901: PHP_FUNCTION(ob_get_clean)
                    902: {
                    903:        if (zend_parse_parameters_none() == FAILURE) {
                    904:                return;
                    905:        }
                    906: 
                    907:        if (php_ob_get_buffer(return_value TSRMLS_CC) == FAILURE) {
                    908:                RETURN_FALSE;
                    909:        }
                    910: 
                    911:        if (!OG(ob_nesting_level)) {
                    912:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete");
                    913:                zval_dtor(return_value);
                    914:                RETURN_FALSE;
                    915:        }
                    916:        if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) {
                    917:                php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s", OG(active_ob_buffer).handler_name);
                    918:                zval_dtor(return_value);
                    919:                RETURN_FALSE;
                    920:        }
                    921: 
                    922:        php_end_ob_buffer(0, 0 TSRMLS_CC);
                    923: }
                    924: /* }}} */
                    925: 
                    926: /* {{{ proto string ob_get_contents(void)
                    927:    Return the contents of the output buffer */
                    928: PHP_FUNCTION(ob_get_contents)
                    929: {
                    930:        if (zend_parse_parameters_none() == FAILURE) {
                    931:                return;
                    932:        }
                    933: 
                    934:        if (php_ob_get_buffer(return_value TSRMLS_CC) == FAILURE) {
                    935:                RETURN_FALSE;
                    936:        }
                    937: }
                    938: /* }}} */
                    939: 
                    940: /* {{{ proto int ob_get_level(void)
                    941:    Return the nesting level of the output buffer */
                    942: PHP_FUNCTION(ob_get_level)
                    943: {
                    944:        if (zend_parse_parameters_none() == FAILURE) {
                    945:                return;
                    946:        }
                    947: 
                    948:        RETURN_LONG(OG(ob_nesting_level));
                    949: }
                    950: /* }}} */
                    951: 
                    952: /* {{{ proto int ob_get_length(void)
                    953:    Return the length of the output buffer */
                    954: PHP_FUNCTION(ob_get_length)
                    955: {
                    956:        if (zend_parse_parameters_none() == FAILURE) {
                    957:                return;
                    958:        }
                    959: 
                    960:        if (php_ob_get_length(return_value TSRMLS_CC) == FAILURE) {
                    961:                RETURN_FALSE;
                    962:        }
                    963: }
                    964: /* }}} */
                    965: 
                    966: /* {{{ proto false|array ob_list_handlers()
                    967:    List all output_buffers in an array */
                    968: PHP_FUNCTION(ob_list_handlers)
                    969: {
                    970:        if (zend_parse_parameters_none() == FAILURE) {
                    971:                return;
                    972:        }
                    973: 
                    974:        array_init(return_value);
                    975: 
                    976:        if (OG(ob_nesting_level)) {
                    977:                if (OG(ob_nesting_level) > 1) {
                    978:                        zend_stack_apply_with_argument(&OG(ob_buffers), ZEND_STACK_APPLY_BOTTOMUP, (int (*)(void *element, void *)) php_ob_list_each, return_value);
                    979:                }
                    980:                php_ob_list_each(&OG(active_ob_buffer), return_value);
                    981:        }
                    982: }
                    983: /* }}} */
                    984: 
                    985: /* {{{ proto false|array ob_get_status([bool full_status])
                    986:    Return the status of the active or all output buffers */
                    987: PHP_FUNCTION(ob_get_status)
                    988: {
                    989:        zend_bool full_status = 0;
                    990: 
                    991:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &full_status) == FAILURE) {
                    992:                return;
                    993:        }
                    994: 
                    995:        array_init(return_value);
                    996: 
                    997:        if (full_status) {
                    998:                if (OG(ob_nesting_level) > 1) {
                    999:                        zend_stack_apply_with_argument(&OG(ob_buffers), ZEND_STACK_APPLY_BOTTOMUP, (int (*)(void *elem, void *))php_ob_buffer_status, return_value);
                   1000:                }
                   1001:                if (OG(ob_nesting_level) > 0 && php_ob_buffer_status(&OG(active_ob_buffer), return_value) == FAILURE) {
                   1002:                        RETURN_FALSE;
                   1003:                }
                   1004:        } else if (OG(ob_nesting_level) > 0) {
                   1005:                add_assoc_long(return_value, "level", OG(ob_nesting_level));
                   1006:                if (OG(active_ob_buffer).internal_output_handler) {
                   1007:                        add_assoc_long(return_value, "type", PHP_OUTPUT_HANDLER_INTERNAL);
                   1008:                } else {
                   1009:                        add_assoc_long(return_value, "type", PHP_OUTPUT_HANDLER_USER);
                   1010:                }
                   1011:                add_assoc_long(return_value, "status", OG(active_ob_buffer).status);
                   1012:                add_assoc_string(return_value, "name", OG(active_ob_buffer).handler_name, 1);
                   1013:                add_assoc_bool(return_value, "del", OG(active_ob_buffer).erase);
                   1014:        }
                   1015: }
                   1016: /* }}} */
                   1017: 
                   1018: /* {{{ proto void ob_implicit_flush([int flag])
                   1019:    Turn implicit flush on/off and is equivalent to calling flush() after every output call */
                   1020: PHP_FUNCTION(ob_implicit_flush)
                   1021: {
                   1022:        long flag = 1;
                   1023: 
                   1024:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flag) == FAILURE) {
                   1025:                return;
                   1026:        }
                   1027: 
                   1028:        if (flag) {
                   1029:                php_start_implicit_flush(TSRMLS_C);
                   1030:        } else {
                   1031:                php_end_implicit_flush(TSRMLS_C);
                   1032:        }
                   1033: }
                   1034: /* }}} */
                   1035: 
                   1036: /* {{{ proto bool output_reset_rewrite_vars(void)
                   1037:    Reset(clear) URL rewriter values */
                   1038: PHP_FUNCTION(output_reset_rewrite_vars)
                   1039: {
                   1040:        if (php_url_scanner_reset_vars(TSRMLS_C) == SUCCESS) {
                   1041:                RETURN_TRUE;
                   1042:        } else {
                   1043:                RETURN_FALSE;
                   1044:        }
                   1045: }
                   1046: /* }}} */
                   1047: 
                   1048: /* {{{ proto bool output_add_rewrite_var(string name, string value)
                   1049:    Add URL rewriter values */
                   1050: PHP_FUNCTION(output_add_rewrite_var)
                   1051: {
                   1052:        char *name, *value;
                   1053:        int name_len, value_len;
                   1054: 
                   1055:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &name, &name_len, &value, &value_len) == FAILURE) {
                   1056:                return;
                   1057:        }
                   1058: 
                   1059:        if (php_url_scanner_add_var(name, name_len, value, value_len, 1 TSRMLS_CC) == SUCCESS) {
                   1060:                RETURN_TRUE;
                   1061:        } else {
                   1062:                RETURN_FALSE;
                   1063:        }
                   1064: }
                   1065: /* }}} */
                   1066: 
                   1067: /*
                   1068:  * Local variables:
                   1069:  * tab-width: 4
                   1070:  * c-basic-offset: 4
                   1071:  * End:
                   1072:  * vim600: sw=4 ts=4 fdm=marker
                   1073:  * vim<600: sw=4 ts=4
                   1074:  */

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