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 */