#include "php_asterisk.h" extern void asterisk_log(char *,char *); extern struct ast_channel *asterisk_get_channel_by_name(char *); /*******************/ /* PHP module part */ /*******************/ AST_MUTEX_DEFINE_STATIC(modlock); PHP_MINFO_FUNCTION(asterisk); PHP_FUNCTION(asterisk_setvariable); PHP_FUNCTION(asterisk_getvariable); PHP_FUNCTION(asterisk_log); /* {{{ asterisk_functions[] * * Every user visible function must have an entry in asterisk_functions[]. */ function_entry asterisk_functions[] = { PHP_FE(asterisk_setvariable, NULL) PHP_FE(asterisk_getvariable, NULL) PHP_FE(asterisk_log, NULL) {NULL, NULL, NULL} }; /* }}} */ /* {{{ asterisk_module_entry */ zend_module_entry asterisk_module_entry = { STANDARD_MODULE_HEADER, "asterisk", asterisk_functions, NULL, NULL, NULL, NULL, PHP_MINFO(asterisk), NO_VERSION_YET, STANDARD_MODULE_PROPERTIES }; /* }}} */ /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(asterisk) { php_info_print_box_start(0); php_printf("

Asterisk PHP extension

\n"); php_printf("

Version 0.1alpha (2005-06-09)

\n"); php_printf("

Authors:

\n"); php_printf("

David Eder <david@eder.us>

\n"); php_info_print_box_end(); DISPLAY_INI_ENTRIES(); } /* }}} */ /* borrowed from res_perl AstAPIBase.c */ struct ast_channel *asterisk_get_channel_by_name(char *name) { struct ast_channel *c=NULL; ast_mutex_lock(&modlock); if((c=ast_get_channel_by_name_locked(name))) ast_mutex_unlock(&c->lock); ast_mutex_unlock(&modlock); return c; } /* {{{ proto int asterisk_setvariable(string channel, string var, string val) Set a channel variable */ PHP_FUNCTION(asterisk_setvariable) { struct ast_channel *chan; char * channel = NULL; int channel_len = 0; char * var = NULL; int var_len = 0; char * val = NULL; int val_len = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss", &channel, &channel_len, &var, &var_len, &val, &val_len) == FAILURE) { return; } chan = (struct ast_channel *)asterisk_get_channel_by_name(channel); if(!chan) { /* ast_log(LOG_WARNING, "No Channel!\n"); */ RETURN_LONG(-1); } pbx_builtin_setvar_helper(chan, var, val); RETURN_LONG(0); } /* }}} */ /* {{{ proto string asterisk_getvariable(string channel, string var) Set a channel variable */ PHP_FUNCTION(asterisk_getvariable) { struct ast_channel *chan; char * channel = NULL; int channel_len = 0; char * var = NULL; int var_len = 0; char * val = NULL; ast_log(LOG_WARNING, "Hello world!\n"); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &channel, &channel_len, &var, &var_len) == FAILURE) { return; } chan = (struct ast_channel *)asterisk_get_channel_by_name(channel); if(!chan) { /* ast_log(LOG_WARNING, "No Channel!\n"); */ RETURN_LONG(-1); } val = pbx_builtin_getvar_helper(chan, var); RETURN_STRING(val, strlen(val)); } /* }}} */ /* {{{ proto string asterisk_log(string message) Log to asterisk */ PHP_FUNCTION(asterisk_log) { char * message = NULL; int message_len = 0; struct ast_channel *chan; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &message, &message_len) == FAILURE) { return; } chan = (struct ast_channel *)asterisk_get_channel_by_name(message); ast_log(LOG_WARNING, message); RETURN_STRING(chan->name, strlen(chan->name)); } /* }}} */ /*************/ /* SAPI part */ /*************/ static char* php_asterisk_read_cookies(TSRMLS_D) { return NULL; } static int php_asterisk_deactivate(TSRMLS_D) { fflush(stdout); return SUCCESS; } static inline size_t php_asterisk_single_write(const char *str, uint str_length) { #ifdef PHP_WRITE_STDOUT long ret; ret = write(STDOUT_FILENO, str, str_length); if (ret <= 0) return 0; return ret; #else size_t ret; ret = fwrite(str, 1, MIN(str_length, 16384), stdout); return ret; #endif } static int php_asterisk_ub_write(const char *str, uint str_length TSRMLS_DC) { const char *ptr = str; uint remaining = str_length; size_t ret; while (remaining > 0) { ret = php_asterisk_single_write(ptr, remaining); if (!ret) { php_handle_aborted_connection(); } ptr += ret; remaining -= ret; } return str_length; } static void php_asterisk_flush(void *server_context) { if (fflush(stdout)==EOF) { php_handle_aborted_connection(); } } static void php_asterisk_send_header(sapi_header_struct *sapi_header, void *server_context TSRMLS_DC) { } static void php_asterisk_log_message(char *message) { fprintf (stderr, "%s\n", message); } static void php_asterisk_register_variables(zval *track_vars_array TSRMLS_DC) { php_import_environment_variables(track_vars_array TSRMLS_CC); } static int php_asterisk_startup(sapi_module_struct *sapi_module) { if (php_module_startup(sapi_module, &asterisk_module_entry, 1)==FAILURE) { return FAILURE; } return SUCCESS; } sapi_module_struct php_asterisk_module = { "asterisk", /* name */ "PHP Asterisk", /* pretty name */ php_asterisk_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ NULL, /* activate */ php_asterisk_deactivate, /* deactivate */ php_asterisk_ub_write, /* unbuffered write */ php_asterisk_flush, /* flush */ NULL, /* get uid */ NULL, /* getenv */ php_error, /* error handler */ NULL, /* header handler */ NULL, /* send headers handler */ php_asterisk_send_header, /* send header handler */ NULL, /* read POST data */ php_asterisk_read_cookies, /* read Cookies */ php_asterisk_register_variables, /* register server variables */ php_asterisk_log_message, /* Log message */ NULL, /* Block interruptions */ NULL, /* Unblock interruptions */ STANDARD_SAPI_MODULE_PROPERTIES }; /* }}} */ int php_asterisk_init(int argc, char **argv PTSRMLS_DC) { zend_llist global_vars; #ifdef ZTS zend_compiler_globals *compiler_globals; zend_executor_globals *executor_globals; php_core_globals *core_globals; sapi_globals_struct *sapi_globals; void ***tsrm_ls; #endif #ifdef HAVE_SIGNAL_H #if defined(SIGPIPE) && defined(SIG_IGN) signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE in standalone mode so that sockets created via fsockopen() don't kill PHP if the remote site closes it. in apache|apxs mode apache does that for us! thies@thieso.net 20000419 */ #endif #endif #ifdef PHP_WIN32 _fmode = _O_BINARY; /*sets default for file streams to binary */ setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */ setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */ setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */ #endif #ifdef ZTS tsrm_startup(1, 1, 0, NULL); #endif #ifdef ZTS compiler_globals = ts_resource(compiler_globals_id); executor_globals = ts_resource(executor_globals_id); core_globals = ts_resource(core_globals_id); sapi_globals = ts_resource(sapi_globals_id); tsrm_ls = ts_resource(0); *ptsrm_ls = tsrm_ls; #endif sapi_startup(&php_asterisk_module); if (php_asterisk_module.startup(&php_asterisk_module)==FAILURE) { return FAILURE; } if (argv) { php_asterisk_module.executable_location = argv[0]; } zend_llist_init(&global_vars, sizeof(char *), NULL, 0); /* Set some Asterisk PHP defaults */ SG(options) |= SAPI_OPTION_NO_CHDIR; zend_alter_ini_entry("register_argc_argv", 19, "1", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); zend_alter_ini_entry("html_errors", 12, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); zend_alter_ini_entry("implicit_flush", 15, "1", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); zend_alter_ini_entry("max_execution_time", 19, "0", 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); SG(request_info).argc=argc; SG(request_info).argv=argv; if (php_request_startup(TSRMLS_C)==FAILURE) { php_module_shutdown(TSRMLS_C); return FAILURE; } SG(headers_sent) = 1; SG(request_info).no_headers = 1; php_register_variable("PHP_SELF", "-", NULL TSRMLS_CC); return SUCCESS; } void php_asterisk_shutdown(TSRMLS_D) { php_request_shutdown((void *) 0); php_module_shutdown(TSRMLS_C); sapi_shutdown(); #ifdef ZTS tsrm_shutdown(); #endif }