All pastes #16515 Raw Edit

Untitled

public text v1 · immutable
#16515 ·published 2005-06-30 17:16 UTC
rendered paste body
/*
   +----------------------------------------------------------------------+
   | PHP Version 5                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2004 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 3.0 of the PHP license,       |
   | that is bundled with this package in the file LICENSE, and is        |
   | available through the world-wide-web at the following url:           |
   | http://www.php.net/license/3_0.txt.                                  |
   | If you did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world-wide-web, please send a note to          |
   | license@php.net so we can mail you a copy immediately.               |
   +----------------------------------------------------------------------+
   | Author: Sascha Schumann <sascha@schumann.cx>                         |
   +----------------------------------------------------------------------+
*/


#ifndef _REENTRANT
#define _REENTRANT
#endif

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#include "php.h"
#include "SAPI.h"
#include "php_main.h"
#include "php_variables.h"
#include "php_ini.h"
#include "ext/standard/php_smart_str.h"

#include <asterisk/pbx.h>
#include <asterisk/logger.h>
#include <asterisk/channel.h>
#include <asterisk/module.h>
#include <asterisk/options.h>
#include <asterisk/utils.h>

#include "../asterisk-1.0.8/build.h"

STANDARD_LOCAL_USER;
LOCAL_USER_DECL;

/* *********************************************************************** *
 * *            PHP SAPI                                                 * *
 * *********************************************************************** */

#define MAX_ARGS 128

typedef struct {
        struct ast_channel *channel;
        int argc;
        char *argv[MAX_ARGS+1];
        int ast_action;
} php_ast_globals;

static php_ast_globals ast_globals;

#define TG(v) (ast_globals.v)

static int sapi_ast_ub_write(const char *str, uint str_length TSRMLS_DC)
{
printf("%s", str);
        ast_verbose("%s", str);
        return str_length;
}

static void sapi_ast_flush(void *server_context)
{
        if (fflush(stdout)==EOF) {
                php_handle_aborted_connection();
        }
}


void sapi_ast_error_handler(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args)
{
#if 0
        char *error_type_str;
        char *buffer;
        int buffer_len;
        TSRMLS_FETCH();

        buffer_len = vspprintf(&buffer, PG(log_errors_max_len), format, args);

        switch (type) {
                case E_ERROR:
                case E_CORE_ERROR:
                case E_COMPILE_ERROR:
                case E_USER_ERROR:
                        error_type_str = "Fatal error";
                        break;
                case E_WARNING:
                case E_CORE_WARNING:
                case E_COMPILE_WARNING:
                case E_USER_WARNING:
                        error_type_str = "Warning";
                        break;
                case E_PARSE:
                        error_type_str = "Parse error";
                        break;
                case E_NOTICE:
                case E_USER_NOTICE:
                        error_type_str = "Notice";
                        break;
                default:
                        error_type_str = "Unknown error";
                        break;
        }

        ast_verbose("PHP %s:  %s in %s on line %d\n", error_type_str, buffer, error_filename, error_lineno);

        efree(buffer);
#endif
}

static int sapi_ast_send_headers(sapi_headers_struct *sapi_headers)
{
        return SAPI_HEADER_SENT_SUCCESSFULLY;
}

static void sapi_ast_log_message(char *message)
{
        ast_verbose("%s", message);
}

static int sapi_ast_read_post(char *buffer, uint count_bytes)
{
        return 0;
}

static char *sapi_ast_read_cookies(void)
{
        return NULL;
}

#define BUF_SIZE 512

static void sapi_ast_register_variables(zval *track_vars_array TSRMLS_DC)
{

        zend_alter_ini_entry("implicit_flush", 15, "1", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
#if 0
        char buf[BUF_SIZE + 1];
        char *p;
        sapi_header_line ctr = {0};

        ctr.line = buf;
        ctr.line_len = snprintf(buf, BUF_SIZE, "Server: %s", BUILD_VERSION);
        sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);

        php_register_variable("PHP_SELF", TG(argv)[0], track_vars_array TSRMLS_CC);
        php_register_variable("SERVER_SOFTWARE", BUILD_VERSION, track_vars_array TSRMLS_CC);
        php_register_variable("SERVER_NAME", "Asterisk", track_vars_array TSRMLS_CC);
/*
        php_register_variable("DOCUMENT_ROOT", ASTAPI_docroot, track_vars_array TSRMLS_CC);
        php_register_variable("PATH_TRANSLATED", SG(request_info).path_translated, track_vars_array TSRMLS_CC);
*/
        php_register_variable("CHANNEL", TG(channel)->name, track_vars_array TSRMLS_CC);

        php_import_environment_variables(track_vars_array TSRMLS_CC);

        zend_error_cb = sapi_ast_error_handler;

/*
        SG(request_info).argc = TG(argc);
        SG(request_info).argv = TG(argv);
*/
#endif
}

static int sapi_ast_startup(sapi_module_struct *sapi_module)
{
        if(php_module_startup(sapi_module, NULL, 0) == FAILURE) {
                return FAILURE;
        } else {
                return SUCCESS;
        }
}

static sapi_module_struct ast_sapi_module = {
        "ast",
        "Asterisk",

        sapi_ast_startup,
        php_module_shutdown_wrapper,

        NULL,                                                                   /* activate */
        NULL,                                                                   /* deactivate */

        sapi_ast_ub_write,
        sapi_ast_flush,
        NULL,                                                                   /* get uid */
        NULL,                                                                   /* getenv */

        php_error,

        NULL,
        sapi_ast_send_headers,
        NULL,
        sapi_ast_read_post,
        sapi_ast_read_cookies,

        sapi_ast_register_variables,
        sapi_ast_log_message,                                                   /* Log message */
        NULL,                                                                   /* Get request time */

        STANDARD_SAPI_MODULE_PROPERTIES
};


/* *********************************************************************** *
 * *            Asterisk Application                                     * *
 * *********************************************************************** */


static char *tdesc      = "PHP for the dialplan";
static char *app        = "PHP";
static char *synopsis   = "Execute PHP code";
static char *descrip    = "  PHP(filename[|option]):  Executes filename as PHP code.\n";



static void ast_module_main(TSRMLS_D)
{
        zend_file_handle file_handle;

        file_handle.type = ZEND_HANDLE_FILENAME;
        file_handle.filename = TG(argv)[0];
        file_handle.free_filename = 0;
        file_handle.opened_path = NULL;

        if (php_request_startup(TSRMLS_C) == FAILURE) {
                return;
        }

ast_verbose("%s start script\n\n", TG(channel)->name);
        php_execute_script(&file_handle TSRMLS_CC);
ast_verbose("%s end script\n\n", TG(channel)->name);
        php_request_shutdown(NULL);
}

static int ast_php_exec(struct ast_channel *chan, void *data)
{
        TSRMLS_FETCH();

        int res = 0;
        struct localuser *u;
        char buf[2048] = "";
        char *tmp = (char *)buf;
        char *stringp;

        TG(argc) = 0;

        if (!data || ast_strlen_zero(data)) {
                ast_log(LOG_WARNING, "PHP requires an argument (script)\n");
                return -1;
        }
        strncpy(buf, data, sizeof(buf) - 1);

        while((TG(argc) < MAX_ARGS && (stringp = strsep(&tmp, "|")))) {
                TG(argv)[TG(argc)++] = stringp;
        }
        TG(argv)[TG(argc)] = NULL;

        LOCAL_USER_ADD(u);

        TG(channel) = chan;

        ast_module_main(TSRMLS_C);


        TG(channel) = NULL;
        while(TG(argc)) TG(argv)[TG(argc)--] = NULL;
        TG(argc) = 0;

ast_verbose("%s completed\n\n", chan->name);
        LOCAL_USER_REMOVE(u);
ast_verbose("%s ended\n\n", chan->name);

        return res;
}

int load_module(void)
{
        sapi_startup(&ast_sapi_module);
        ast_sapi_module.startup(&ast_sapi_module);
        SG(server_context) = (void *) 1;
        return ast_register_application(app, ast_php_exec, synopsis, descrip);
}

int unload_module(void)
{
        if (SG(server_context) != NULL) {
                ast_sapi_module.shutdown(&ast_sapi_module);
                sapi_shutdown();
        }

        STANDARD_HANGUP_LOCALUSERS;
        return ast_unregister_application(app);
}

char *description(void)
{
        return tdesc;
}

int usecount(void)
{
        int res;
        STANDARD_USECOUNT(res);
        return res;
}

char *key()
{
        return ASTERISK_GPL_KEY;
}




/* *********************************************************************** *
 * *            PHP Module                                               * *
 * *********************************************************************** */
/* TODO */