Annotation of embedaddon/php/main/output.c, revision 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>