2007-10-12 03:28:59 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2010-02-06 03:38:24 +00:00
* Copyright ( C ) 2005 - 2010 , Anthony Minessale II < anthm @ freeswitch . org >
2007-10-12 03:28:59 +00:00
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2007-10-12 03:28:59 +00:00
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2007-10-23 14:45:22 +00:00
* Bret McDanel < trixter AT 0xdecafbad . com >
2008-08-06 23:33:58 +00:00
* John Wehle ( john @ feith . com )
2008-09-26 19:48:55 +00:00
* Raymond Chandler < intralanman @ gmail . com >
2007-10-12 03:28:59 +00:00
*
* mod_voicemail . c - - Voicemail Module
*
*/
# include <switch.h>
2008-05-27 04:54:52 +00:00
# ifdef _MSC_VER /* compilers are stupid sometimes */
2007-10-12 20:14:41 +00:00
# define TRY_CODE(code) for(;;) {status = code; if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { goto end; } break;}
# else
2007-11-02 21:58:04 +00:00
# define TRY_CODE(code) do { status = code; if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { goto end; } break;} while(status)
2007-10-12 20:14:41 +00:00
# endif
2007-10-12 03:28:59 +00:00
SWITCH_MODULE_LOAD_FUNCTION ( mod_voicemail_load ) ;
2009-04-25 14:16:32 +00:00
SWITCH_MODULE_SHUTDOWN_FUNCTION ( mod_voicemail_shutdown ) ;
SWITCH_MODULE_DEFINITION ( mod_voicemail , mod_voicemail_load , mod_voicemail_shutdown , NULL ) ;
2008-10-29 17:28:12 +00:00
# define VM_EVENT_MAINT "vm::maintenance"
2007-10-12 03:28:59 +00:00
2008-03-07 23:21:08 +00:00
# define VM_MAX_GREETINGS 9
2008-09-08 21:56:07 +00:00
static switch_status_t voicemail_inject ( const char * data ) ;
2008-07-17 19:46:25 +00:00
2009-04-25 14:16:32 +00:00
static const char * global_cf = " voicemail.conf " ;
2007-10-12 03:28:59 +00:00
static struct {
switch_hash_t * profile_hash ;
2007-12-26 17:37:13 +00:00
int debug ;
2009-04-24 14:27:19 +00:00
int message_query_exact_match ;
2009-04-25 14:16:32 +00:00
switch_mutex_t * mutex ;
2007-12-26 17:37:13 +00:00
switch_memory_pool_t * pool ;
2007-10-12 03:28:59 +00:00
} globals ;
2008-09-27 20:34:47 +00:00
typedef enum {
VM_DATE_FIRST ,
VM_DATE_LAST ,
VM_DATE_NEVER
} date_location_t ;
2009-06-20 19:55:30 +00:00
typedef enum {
PFLAG_DESTROY = 1 < < 0
} vm_flags_t ;
2009-06-20 03:29:43 +00:00
2009-07-27 18:44:30 +00:00
typedef enum {
VM_MOVE_NEXT ,
VM_MOVE_PREV
} msg_move_t ;
2009-06-20 03:29:43 +00:00
# define VM_PROFILE_CONFIGITEM_COUNT 100
2007-10-12 03:28:59 +00:00
struct vm_profile {
2007-12-26 17:37:13 +00:00
char * name ;
char * dbname ;
2007-10-12 03:28:59 +00:00
char * odbc_dsn ;
char * odbc_user ;
char * odbc_pass ;
2007-12-26 17:37:13 +00:00
char terminator_key [ 2 ] ;
char play_new_messages_key [ 2 ] ;
char play_saved_messages_key [ 2 ] ;
2009-04-06 16:36:33 +00:00
char login_keys [ 16 ] ;
2008-05-27 04:54:52 +00:00
char main_menu_key [ 2 ] ;
2008-12-18 22:53:01 +00:00
char skip_greet_key [ 2 ] ;
2009-07-27 20:46:05 +00:00
char skip_info_key [ 2 ] ;
2007-12-26 17:37:13 +00:00
char config_menu_key [ 2 ] ;
char record_greeting_key [ 2 ] ;
char choose_greeting_key [ 2 ] ;
char record_name_key [ 2 ] ;
2008-08-20 22:06:04 +00:00
char change_pass_key [ 2 ] ;
2007-12-26 17:37:13 +00:00
char record_file_key [ 2 ] ;
char listen_file_key [ 2 ] ;
char save_file_key [ 2 ] ;
char delete_file_key [ 2 ] ;
char undelete_file_key [ 2 ] ;
char email_key [ 2 ] ;
char callback_key [ 2 ] ;
char pause_key [ 2 ] ;
char restart_key [ 2 ] ;
char ff_key [ 2 ] ;
char rew_key [ 2 ] ;
2009-07-27 18:44:30 +00:00
char prev_msg_key [ 2 ] ;
char next_msg_key [ 2 ] ;
2007-12-26 17:37:13 +00:00
char urgent_key [ 2 ] ;
char operator_key [ 2 ] ;
2008-05-20 17:19:14 +00:00
char vmain_key [ 2 ] ;
2008-09-08 21:56:07 +00:00
char forward_key [ 2 ] ;
char prepend_key [ 2 ] ;
2007-12-26 17:37:13 +00:00
char file_ext [ 10 ] ;
char * record_title ;
char * record_comment ;
char * record_copyright ;
char * operator_ext ;
2008-05-20 17:19:14 +00:00
char * vmain_ext ;
2007-12-26 17:37:13 +00:00
char * tone_spec ;
char * storage_dir ;
char * callback_dialplan ;
char * callback_context ;
char * email_body ;
char * email_headers ;
2008-06-03 22:01:26 +00:00
char * notify_email_body ;
char * notify_email_headers ;
2007-12-26 17:37:13 +00:00
char * web_head ;
char * web_tail ;
char * email_from ;
char * date_fmt ;
2009-10-01 22:43:44 +00:00
char * convert_cmd ;
char * convert_ext ;
2008-09-27 20:34:47 +00:00
date_location_t play_date_announcement ;
2007-12-26 17:37:13 +00:00
uint32_t digit_timeout ;
uint32_t max_login_attempts ;
2008-01-03 22:04:19 +00:00
uint32_t min_record_len ;
2007-12-26 17:37:13 +00:00
uint32_t max_record_len ;
2009-02-26 20:46:08 +00:00
uint32_t max_retries ;
2007-12-26 17:37:13 +00:00
switch_mutex_t * mutex ;
uint32_t record_threshold ;
uint32_t record_silence_hits ;
uint32_t record_sample_rate ;
2008-10-01 13:06:59 +00:00
switch_bool_t auto_playback_recordings ;
2009-04-25 14:16:32 +00:00
switch_thread_rwlock_t * rwlock ;
switch_memory_pool_t * pool ;
2009-06-20 19:55:30 +00:00
uint32_t flags ;
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
switch_xml_config_item_t config [ VM_PROFILE_CONFIGITEM_COUNT ] ;
switch_xml_config_string_options_t config_str_pool ;
2007-10-12 03:28:59 +00:00
} ;
typedef struct vm_profile vm_profile_t ;
2009-11-25 00:23:07 +00:00
switch_cache_db_handle_t * vm_get_db_handle ( vm_profile_t * profile )
{
switch_cache_db_connection_options_t options = { { 0 } } ;
switch_cache_db_handle_t * dbh = NULL ;
2010-02-06 03:38:24 +00:00
2010-01-13 18:02:42 +00:00
if ( ! zstr ( profile - > odbc_dsn ) ) {
2009-11-25 00:23:07 +00:00
options . odbc_options . dsn = profile - > odbc_dsn ;
options . odbc_options . user = profile - > odbc_user ;
options . odbc_options . pass = profile - > odbc_pass ;
2010-02-06 03:38:24 +00:00
if ( switch_cache_db_get_db_handle ( & dbh , SCDB_TYPE_ODBC , & options ) ! = SWITCH_STATUS_SUCCESS )
dbh = NULL ;
2009-11-25 00:23:07 +00:00
return dbh ;
} else {
options . core_db_options . db_path = profile - > dbname ;
2010-02-06 03:38:24 +00:00
if ( switch_cache_db_get_db_handle ( & dbh , SCDB_TYPE_CORE_DB , & options ) ! = SWITCH_STATUS_SUCCESS )
dbh = NULL ;
2009-11-25 00:23:07 +00:00
return dbh ;
}
}
2007-10-12 03:28:59 +00:00
static switch_status_t vm_execute_sql ( vm_profile_t * profile , char * sql , switch_mutex_t * mutex )
{
2009-11-25 00:23:07 +00:00
switch_cache_db_handle_t * dbh = NULL ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2007-10-12 03:28:59 +00:00
if ( mutex ) {
switch_mutex_lock ( mutex ) ;
}
2009-11-25 00:23:07 +00:00
if ( ! ( dbh = vm_get_db_handle ( profile ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Opening DB \n " ) ;
goto end ;
2007-12-26 17:37:13 +00:00
}
2007-10-12 03:28:59 +00:00
2009-11-25 00:23:07 +00:00
status = switch_cache_db_execute_sql ( dbh , sql , NULL ) ;
2008-05-27 04:54:52 +00:00
end :
2010-02-06 03:38:24 +00:00
2009-11-25 00:23:07 +00:00
switch_cache_db_release_db_handle ( & dbh ) ;
2007-10-12 03:28:59 +00:00
if ( mutex ) {
switch_mutex_unlock ( mutex ) ;
}
2009-11-25 00:23:07 +00:00
2007-12-26 17:37:13 +00:00
return status ;
2007-10-12 03:28:59 +00:00
}
2010-02-06 03:38:24 +00:00
static switch_bool_t vm_execute_sql_callback ( vm_profile_t * profile , switch_mutex_t * mutex , char * sql , switch_core_db_callback_func_t callback ,
void * pdata )
2007-10-12 03:28:59 +00:00
{
switch_bool_t ret = SWITCH_FALSE ;
char * errmsg = NULL ;
2009-11-25 00:23:07 +00:00
switch_cache_db_handle_t * dbh = NULL ;
2010-02-06 03:38:24 +00:00
2007-10-12 03:28:59 +00:00
if ( mutex ) {
2007-12-26 17:37:13 +00:00
switch_mutex_lock ( mutex ) ;
}
2007-10-12 03:28:59 +00:00
2009-11-25 00:23:07 +00:00
if ( ! ( dbh = vm_get_db_handle ( profile ) ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Opening DB \n " ) ;
goto end ;
}
2009-11-25 00:23:07 +00:00
switch_cache_db_execute_sql_callback ( dbh , sql , callback , pdata , & errmsg ) ;
2007-10-12 03:28:59 +00:00
2009-11-25 00:23:07 +00:00
if ( errmsg ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL ERR: [%s] %s \n " , sql , errmsg ) ;
free ( errmsg ) ;
2007-12-26 17:37:13 +00:00
}
2007-10-12 03:28:59 +00:00
2008-05-27 04:54:52 +00:00
end :
2009-11-25 00:23:07 +00:00
switch_cache_db_release_db_handle ( & dbh ) ;
2007-10-12 03:28:59 +00:00
if ( mutex ) {
2007-12-26 17:37:13 +00:00
switch_mutex_unlock ( mutex ) ;
}
2009-11-25 00:23:07 +00:00
2007-10-12 03:28:59 +00:00
return ret ;
}
2009-11-25 00:23:07 +00:00
2007-10-12 03:28:59 +00:00
static char vm_sql [ ] =
2008-03-18 22:13:32 +00:00
" CREATE TABLE voicemail_msgs ( \n "
2007-11-26 23:41:00 +00:00
" created_epoch INTEGER, \n "
2008-05-27 04:54:52 +00:00
" read_epoch INTEGER, \n "
" username VARCHAR(255), \n "
" domain VARCHAR(255), \n "
" uuid VARCHAR(255), \n "
" cid_name VARCHAR(255), \n "
" cid_number VARCHAR(255), \n "
" in_folder VARCHAR(255), \n "
2010-02-06 03:38:24 +00:00
" file_path VARCHAR(255), \n "
" message_len INTEGER, \n " " flags VARCHAR(255), \n " " read_flags VARCHAR(255), \n " " forwarded_by VARCHAR(255) \n " " ); \n " ;
2007-10-12 03:28:59 +00:00
static char vm_pref_sql [ ] =
" CREATE TABLE voicemail_prefs ( \n "
2008-05-27 04:54:52 +00:00
" username VARCHAR(255), \n "
2010-02-06 03:38:24 +00:00
" domain VARCHAR(255), \n "
" name_path VARCHAR(255), \n " " greeting_path VARCHAR(255), \n " " password VARCHAR(255) \n " " ); \n " ;
2007-10-12 03:28:59 +00:00
2009-02-28 03:56:38 +00:00
static char * vm_index_list [ ] = {
" create index voicemail_msgs_idx1 on voicemail_msgs(created_epoch) " ,
" create index voicemail_msgs_idx2 on voicemail_msgs(username) " ,
" create index voicemail_msgs_idx3 on voicemail_msgs(domain) " ,
" create index voicemail_msgs_idx4 on voicemail_msgs(uuid) " ,
" create index voicemail_msgs_idx5 on voicemail_msgs(in_folder) " ,
" create index voicemail_msgs_idx6 on voicemail_msgs(read_flags) " ,
2010-01-13 01:32:01 +00:00
" create index voicemail_msgs_idx7 on voicemail_msgs(forwarded_by) " ,
2009-02-28 03:56:38 +00:00
" create index voicemail_prefs_idx1 on voicemail_prefs(username) " ,
" create index voicemail_prefs_idx2 on voicemail_prefs(domain) " ,
NULL
} ;
2009-06-20 19:55:30 +00:00
static void free_profile ( vm_profile_t * profile )
{
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Destroying Profile %s \n " , profile - > name ) ;
switch_core_destroy_memory_pool ( & profile - > pool ) ;
}
2009-04-25 14:16:32 +00:00
2010-02-06 03:38:24 +00:00
static void destroy_profile ( const char * profile_name , switch_bool_t block )
2007-10-12 03:28:59 +00:00
{
vm_profile_t * profile = NULL ;
2009-04-25 14:16:32 +00:00
switch_mutex_lock ( globals . mutex ) ;
if ( ( profile = switch_core_hash_find ( globals . profile_hash , profile_name ) ) ) {
switch_core_hash_delete ( globals . profile_hash , profile_name ) ;
}
switch_mutex_unlock ( globals . mutex ) ;
2007-10-12 03:28:59 +00:00
2009-04-25 14:16:32 +00:00
if ( ! profile ) {
2009-06-20 19:55:30 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " [%s] Invalid Profile \n " , profile_name ) ;
2009-04-25 14:16:32 +00:00
return ;
}
2007-10-12 03:28:59 +00:00
2009-06-20 19:55:30 +00:00
if ( block ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " [%s] Waiting for write lock \n " , profile - > name ) ;
2009-06-20 19:55:30 +00:00
switch_thread_rwlock_wrlock ( profile - > rwlock ) ;
} else {
if ( switch_thread_rwlock_trywrlock ( profile - > rwlock ) ! = SWITCH_STATUS_SUCCESS ) {
/* Lock failed, set the destroy flag so it'll be destroyed whenever its not in use anymore */
switch_set_flag ( profile , PFLAG_DESTROY ) ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " [%s] Profile is in use, memory will be freed whenever its no longer in use \n " ,
profile - > name ) ;
2009-06-20 19:55:30 +00:00
return ;
}
2007-10-12 03:28:59 +00:00
}
2010-02-06 03:38:24 +00:00
2009-06-20 19:55:30 +00:00
free_profile ( profile ) ;
2009-04-25 14:16:32 +00:00
}
2007-12-26 17:37:13 +00:00
2009-06-20 03:29:43 +00:00
/* Static buffer, 2 bytes */
static switch_xml_config_string_options_t config_dtmf = { NULL , 2 , " [0-9# \\ *] " } ;
static switch_xml_config_string_options_t config_login_keys = { NULL , 16 , " [0-9# \\ *]* " } ;
static switch_xml_config_string_options_t config_file_ext = { NULL , 10 , NULL } ;
static switch_xml_config_int_options_t config_int_0_10000 = { SWITCH_TRUE , 0 , SWITCH_TRUE , 10000 } ;
static switch_xml_config_int_options_t config_int_0_1000 = { SWITCH_TRUE , 0 , SWITCH_TRUE , 1000 } ;
static switch_xml_config_int_options_t config_int_digit_timeout = { SWITCH_TRUE , 0 , SWITCH_TRUE , 30000 } ;
static switch_xml_config_int_options_t config_int_max_logins = { SWITCH_TRUE , 0 , SWITCH_TRUE , 10 } ;
static switch_xml_config_int_options_t config_int_ht_0 = { SWITCH_TRUE , 0 } ;
static switch_xml_config_enum_item_t config_play_date_announcement [ ] = {
2010-02-06 03:38:24 +00:00
{ " first " , VM_DATE_FIRST } ,
{ " last " , VM_DATE_LAST } ,
{ " never " , VM_DATE_NEVER } ,
{ NULL , 0 }
2009-06-20 03:29:43 +00:00
} ;
2010-02-06 03:38:24 +00:00
static switch_status_t vm_config_email_callback ( switch_xml_config_item_t * item , const char * newvalue , switch_config_callback_type_t callback_type ,
switch_bool_t changed )
2009-06-20 03:29:43 +00:00
{
2010-02-06 03:38:24 +00:00
vm_profile_t * profile = ( vm_profile_t * ) item - > data ;
2009-06-20 03:29:43 +00:00
switch_assert ( profile ) ;
2010-02-06 03:38:24 +00:00
if ( callback_type = = CONFIG_LOAD | | callback_type = = CONFIG_RELOAD ) {
2009-06-20 03:29:43 +00:00
char * email_headers = NULL , * email_body = NULL ;
if ( newvalue ) {
switch_stream_handle_t stream ;
SWITCH_STANDARD_STREAM ( stream ) ;
2010-02-06 03:38:24 +00:00
if ( switch_stream_write_file_contents ( & stream , newvalue ) = = SWITCH_STATUS_SUCCESS ) {
2009-06-20 03:29:43 +00:00
email_headers = switch_core_strdup ( profile - > pool , stream . data ) ;
if ( ( email_body = strstr ( email_headers , " \n \n " ) ) ) {
* email_body = ' \0 ' ;
email_body + = 2 ;
} else if ( ( email_body = strstr ( email_headers , " \r \n \r \n " ) ) ) {
* email_body = ' \0 ' ;
email_body + = 4 ;
}
}
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
free ( stream . data ) ;
}
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
if ( email_headers ) {
profile - > email_headers = email_headers ;
}
if ( email_body ) {
profile - > email_body = email_body ;
}
}
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2010-02-06 03:38:24 +00:00
static switch_status_t vm_config_notify_callback ( switch_xml_config_item_t * item , const char * newvalue , switch_config_callback_type_t callback_type ,
switch_bool_t changed )
2009-06-20 03:29:43 +00:00
{
2010-02-06 03:38:24 +00:00
vm_profile_t * profile = ( vm_profile_t * ) item - > data ;
2009-06-20 03:29:43 +00:00
switch_assert ( profile ) ;
2010-02-06 03:38:24 +00:00
if ( callback_type = = CONFIG_LOAD | | callback_type = = CONFIG_RELOAD ) {
2009-06-20 03:29:43 +00:00
char * email_headers = NULL , * email_body = NULL ;
if ( newvalue ) {
switch_stream_handle_t stream ;
SWITCH_STANDARD_STREAM ( stream ) ;
2010-02-06 03:38:24 +00:00
if ( switch_stream_write_file_contents ( & stream , newvalue ) = = SWITCH_STATUS_SUCCESS ) {
2009-06-20 03:29:43 +00:00
email_headers = switch_core_strdup ( profile - > pool , stream . data ) ;
if ( ( email_body = strstr ( email_headers , " \n \n " ) ) ) {
* email_body = ' \0 ' ;
email_body + = 2 ;
} else if ( ( email_body = strstr ( email_headers , " \r \n \r \n " ) ) ) {
* email_body = ' \0 ' ;
email_body + = 4 ;
}
}
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
free ( stream . data ) ;
}
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
if ( email_headers ) {
profile - > notify_email_headers = email_headers ;
}
if ( email_body ) {
profile - > notify_email_body = email_body ;
}
}
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2010-02-06 03:38:24 +00:00
static switch_status_t vm_config_web_callback ( switch_xml_config_item_t * item , const char * newvalue , switch_config_callback_type_t callback_type ,
switch_bool_t changed )
2009-06-20 03:29:43 +00:00
{
2010-02-06 03:38:24 +00:00
vm_profile_t * profile = ( vm_profile_t * ) item - > data ;
2009-06-20 03:29:43 +00:00
switch_assert ( profile ) ;
2010-02-06 03:38:24 +00:00
if ( callback_type = = CONFIG_LOAD | | callback_type = = CONFIG_RELOAD ) {
2009-06-20 03:29:43 +00:00
char * web_head = NULL , * web_tail = NULL ;
if ( newvalue ) {
switch_stream_handle_t stream ;
SWITCH_STANDARD_STREAM ( stream ) ;
2010-02-06 03:38:24 +00:00
if ( switch_stream_write_file_contents ( & stream , newvalue ) = = SWITCH_STATUS_SUCCESS ) {
web_head = switch_core_strdup ( profile - > pool , stream . data ) ;
2009-06-20 03:29:43 +00:00
if ( ( web_tail = strstr ( web_head , " <!break> \n " ) ) ) {
* web_tail = ' \0 ' ;
web_tail + = 9 ;
} else if ( ( web_tail = strstr ( web_head , " <!break> \r \n " ) ) ) {
* web_tail = ' \0 ' ;
web_tail + = 10 ;
}
}
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
free ( stream . data ) ;
}
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
if ( web_head ) {
2010-02-06 03:38:24 +00:00
profile - > web_head = web_head ;
2009-06-20 03:29:43 +00:00
}
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
if ( web_tail ) {
profile - > web_tail = web_tail ;
}
}
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2010-02-06 03:38:24 +00:00
static switch_status_t vm_config_validate_samplerate ( switch_xml_config_item_t * item , const char * newvalue , switch_config_callback_type_t callback_type ,
switch_bool_t changed )
2009-06-20 03:29:43 +00:00
{
if ( ( callback_type = = CONFIG_LOAD | | callback_type = = CONFIG_RELOAD ) & & newvalue ) {
2010-02-06 03:38:24 +00:00
int val = * ( int * ) item - > ptr ;
2009-11-06 23:19:15 +00:00
if ( val ! = 0 & & ! switch_is_valid_rate ( val ) ) {
2009-06-20 03:29:43 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Invalid samplerate %s \n " , newvalue ) ;
return SWITCH_STATUS_FALSE ;
}
}
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}
/*!
* \ brief Sets the profile ' s configuration instructions
*/
vm_profile_t * profile_set_config ( vm_profile_t * profile )
{
int i = 0 ;
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
profile - > config_str_pool . pool = profile - > pool ;
/*
2010-02-06 03:38:24 +00:00
SWITCH _CONFIG_SET_ITEM ( item , " key " , type , flags ,
pointer , default , options , help_syntax , help_description )
*/
/* DTMFs */
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " terminator-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > terminator_key , " # " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " play-new-messages-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > play_new_messages_key , " 1 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " play-saved-messages-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > play_saved_messages_key , " 2 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " login-keys " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > login_keys , " 0 " , & config_login_keys , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " main-menu-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > main_menu_key , " 0 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " skip-greet-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > skip_greet_key , " # " , & config_dtmf , NULL , NULL ) ;
2009-07-27 20:46:05 +00:00
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " skip-info-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
2010-02-06 03:38:24 +00:00
& profile - > skip_info_key , " " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " config-menu-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > config_menu_key , " 5 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " record-greeting-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > record_greeting_key , " 1 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " choose-greeting-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > choose_greeting_key , " 2 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " record-name-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > record_name_key , " 3 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " change-pass-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > change_pass_key , " 6 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " record-file-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > record_file_key , " 3 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " listen-file-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > listen_file_key , " 1 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " save-file-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > save_file_key , " 2 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " delete-file-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > delete_file_key , " 7 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " undelete-file-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > undelete_file_key , " 8 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " email-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE , & profile - > email_key , " 4 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " callback-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > callback_key , " 5 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " pause-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE , & profile - > pause_key , " 0 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " restart-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > restart_key , " 1 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " ff-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE , & profile - > ff_key , " 6 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " rew-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE , & profile - > rew_key , " 4 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " previous-message-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > prev_msg_key , " " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " next-message-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > next_msg_key , " " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " urgent-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > urgent_key , " * " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " operator-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > operator_key , " " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " vmain-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE , & profile - > vmain_key , " " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " vmain-extension " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > vmain_ext , " " , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " forward-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > forward_key , " 8 " , & config_dtmf , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " prepend-key " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > prepend_key , " 1 " , & config_dtmf , NULL , NULL ) ;
2009-06-20 03:29:43 +00:00
/* Other settings */
2010-02-06 03:38:24 +00:00
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " file-extension " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > file_ext , " wav " , & config_file_ext , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " record-title " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > record_title , " FreeSWITCH Voicemail " , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " record-comment " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > record_comment , " FreeSWITCH Voicemail " , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " record-copyright " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > record_copyright , " http://www.freeswitch.org " , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " operator-extension " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > operator_ext , " " , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " tone-spec " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > tone_spec , " %(1000, 0, 640) " , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " storage-dir " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > storage_dir , " " , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " callback-dialplan " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > callback_dialplan , " XML " , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " callback-context " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > callback_context , " default " , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " notify-email-body " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > notify_email_body , NULL , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " notify-email-headers " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > notify_email_headers , NULL , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " play-date-announcement " , SWITCH_CONFIG_ENUM , CONFIG_RELOADABLE ,
& profile - > play_date_announcement , VM_DATE_FIRST , & config_play_date_announcement , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " convert-cmd " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
2009-10-01 22:43:44 +00:00
& profile - > convert_cmd , NULL , & profile - > config_str_pool , NULL , NULL ) ;
2010-02-06 03:38:24 +00:00
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " convert-ext " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
2009-10-01 22:43:44 +00:00
& profile - > convert_ext , NULL , & profile - > config_str_pool , NULL , NULL ) ;
2010-02-06 03:38:24 +00:00
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " digit-timeout " , SWITCH_CONFIG_INT , CONFIG_RELOADABLE ,
& profile - > digit_timeout , 10000 , & config_int_digit_timeout , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " max-login-attempts " , SWITCH_CONFIG_INT , CONFIG_RELOADABLE ,
& profile - > max_login_attempts , 3 , & config_int_max_logins , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " min-record-len " , SWITCH_CONFIG_INT , CONFIG_RELOADABLE ,
& profile - > min_record_len , 3 , & config_int_0_10000 , " seconds " , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " max-record-len " , SWITCH_CONFIG_INT , CONFIG_RELOADABLE ,
& profile - > max_record_len , 300 , & config_int_0_1000 , " seconds " , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " max-retries " , SWITCH_CONFIG_INT , CONFIG_RELOADABLE ,
& profile - > max_retries , 3 , & config_int_ht_0 , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " record-silence-threshold " , SWITCH_CONFIG_INT , CONFIG_RELOADABLE ,
& profile - > record_threshold , 200 , & config_int_0_10000 , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " record-silence-hits " , SWITCH_CONFIG_INT , CONFIG_RELOADABLE ,
& profile - > record_silence_hits , 2 , & config_int_0_1000 , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM_CALLBACK ( profile - > config [ i + + ] , " record-sample-rate " , SWITCH_CONFIG_INT , CONFIG_RELOADABLE ,
& profile - > record_sample_rate , 0 , NULL , vm_config_validate_samplerate , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " email_headers " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > email_headers , NULL , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " email_body " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > email_body , NULL , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " email_email-from " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > email_from , NULL , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " email_date-fmt " , SWITCH_CONFIG_STRING , CONFIG_RELOADABLE ,
& profile - > date_fmt , " %A, %B %d %Y, %I %M %p " , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM ( profile - > config [ i + + ] , " odbc-dsn " , SWITCH_CONFIG_STRING , 0 , & profile - > odbc_dsn , NULL , & profile - > config_str_pool , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM_CALLBACK ( profile - > config [ i + + ] , " email_template-file " , SWITCH_CONFIG_CUSTOM , CONFIG_RELOADABLE ,
NULL , NULL , profile , vm_config_email_callback , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM_CALLBACK ( profile - > config [ i + + ] , " email_notify-template-file " , SWITCH_CONFIG_CUSTOM , CONFIG_RELOADABLE ,
NULL , NULL , profile , vm_config_notify_callback , NULL , NULL ) ;
SWITCH_CONFIG_SET_ITEM_CALLBACK ( profile - > config [ i + + ] , " web-template-file " , SWITCH_CONFIG_CUSTOM , CONFIG_RELOADABLE ,
NULL , NULL , profile , vm_config_web_callback , NULL , NULL ) ;
2009-06-20 03:29:43 +00:00
switch_assert ( i < VM_PROFILE_CONFIGITEM_COUNT ) ;
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
return profile ;
}
2010-02-06 03:38:24 +00:00
static vm_profile_t * load_profile ( const char * profile_name )
2009-04-25 14:16:32 +00:00
{
vm_profile_t * profile = NULL ;
2009-06-20 03:29:43 +00:00
switch_xml_t x_profiles , x_profile , cfg , xml , x_email , param ;
switch_event_t * event = NULL ;
2009-12-10 21:04:33 +00:00
switch_cache_db_handle_t * dbh = NULL ;
2007-12-26 17:37:13 +00:00
2009-04-25 14:16:32 +00:00
if ( ! ( xml = switch_xml_open_cfg ( global_cf , & cfg , NULL ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Open of %s failed \n " , global_cf ) ;
return profile ;
2007-10-12 03:28:59 +00:00
}
if ( ! ( x_profiles = switch_xml_child ( cfg , " profiles " ) ) ) {
2007-12-26 17:37:13 +00:00
goto end ;
}
2009-04-25 14:16:32 +00:00
if ( ( x_profile = switch_xml_find_child ( x_profiles , " profile " , " name " , profile_name ) ) ) {
switch_memory_pool_t * pool ;
2009-06-20 03:29:43 +00:00
int x , count ;
2009-11-25 00:23:07 +00:00
char * errmsg ;
2007-10-23 14:45:22 +00:00
2009-04-25 14:16:32 +00:00
if ( switch_core_new_memory_pool ( & pool ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Pool Failure \n " ) ;
goto end ;
}
2009-06-20 03:29:43 +00:00
if ( ! ( profile = switch_core_alloc ( pool , sizeof ( vm_profile_t ) ) ) ) {
2009-04-25 14:16:32 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Alloc Failure \n " ) ;
switch_core_destroy_memory_pool ( & pool ) ;
2009-06-20 03:29:43 +00:00
goto end ;
2009-04-25 14:16:32 +00:00
}
profile - > pool = pool ;
2009-06-20 03:29:43 +00:00
profile_set_config ( profile ) ;
2009-04-25 14:16:32 +00:00
2009-06-20 03:29:43 +00:00
/* Add the params to the event structure */
count = switch_event_import_xml ( switch_xml_child ( x_profile , " param " ) , " name " , " value " , & event ) ;
/* Take care of the custom config structure */
2007-12-26 17:37:13 +00:00
if ( ( x_email = switch_xml_child ( x_profile , " email " ) ) ) {
if ( ( param = switch_xml_child ( x_email , " body " ) ) ) {
2009-06-20 03:29:43 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " email_body " , param - > txt ) ;
2007-12-26 17:37:13 +00:00
}
if ( ( param = switch_xml_child ( x_email , " headers " ) ) ) {
2009-06-20 03:29:43 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " email_headers " , param - > txt ) ;
2007-12-26 17:37:13 +00:00
}
2010-02-06 03:38:24 +00:00
2007-12-15 04:58:44 +00:00
for ( param = switch_xml_child ( x_email , " param " ) ; param ; param = param - > next ) {
2007-12-26 17:37:13 +00:00
char * var , * val ;
2009-06-20 03:29:43 +00:00
char buf [ 2048 ] ;
2010-02-06 03:38:24 +00:00
if ( ( var = ( char * ) switch_xml_attr_soft ( param , " name " ) ) & & ( val = ( char * ) switch_xml_attr_soft ( param , " value " ) ) ) {
2009-06-20 03:29:43 +00:00
switch_snprintf ( buf , 2048 , " email_%s " , var ) ;
2010-02-06 03:38:24 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , buf , val ) ;
2007-12-26 17:37:13 +00:00
}
}
}
2007-10-23 14:45:22 +00:00
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
if ( switch_xml_config_parse_event ( event , count , SWITCH_FALSE , profile - > config ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Failed to process configuration \n " ) ;
switch_core_destroy_memory_pool ( & pool ) ;
goto end ;
}
2010-02-06 03:38:24 +00:00
2009-06-20 03:29:43 +00:00
switch_thread_rwlock_create ( & profile - > rwlock , pool ) ;
profile - > name = switch_core_strdup ( pool , profile_name ) ;
2007-12-26 17:37:13 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( profile - > odbc_dsn ) ) {
2009-06-20 03:29:43 +00:00
if ( ( profile - > odbc_user = strchr ( profile - > odbc_dsn , ' : ' ) ) ) {
* ( profile - > odbc_user + + ) = ' \0 ' ;
if ( ( profile - > odbc_pass = strchr ( profile - > odbc_user , ' : ' ) ) ) {
* ( profile - > odbc_pass + + ) = ' \0 ' ;
2008-09-27 20:34:47 +00:00
}
2007-12-26 17:37:13 +00:00
}
}
2009-06-20 03:29:43 +00:00
profile - > dbname = switch_core_sprintf ( profile - > pool , " voicemail_%s " , profile_name ) ;
2009-04-25 14:16:32 +00:00
2009-11-25 00:23:07 +00:00
if ( ! ( dbh = vm_get_db_handle ( profile ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Cannot open DB! \n " ) ;
goto end ;
}
2010-02-06 03:38:24 +00:00
switch_cache_db_test_reactive ( dbh , " select count(forwarded_by) from voicemail_msgs " , NULL ,
" alter table voicemail_msgs add forwarded_by varchar(255) " ) ;
2010-01-13 01:32:01 +00:00
switch_cache_db_test_reactive ( dbh , " select count(forwarded_by) from voicemail_msgs " , " drop table voicemail_msgs " , vm_sql ) ;
2010-02-06 03:38:24 +00:00
2009-11-25 00:23:07 +00:00
switch_cache_db_test_reactive ( dbh , " select count(username) from voicemail_prefs " , " drop table voicemail_prefs " , vm_pref_sql ) ;
switch_cache_db_test_reactive ( dbh , " select count(password) from voicemail_prefs " , NULL , " alter table voicemail_prefs add password varchar(255) " ) ;
2010-02-06 03:38:24 +00:00
2009-11-25 00:23:07 +00:00
for ( x = 0 ; vm_index_list [ x ] ; x + + ) {
errmsg = NULL ;
switch_cache_db_execute_sql ( dbh , vm_index_list [ x ] , & errmsg ) ;
switch_safe_free ( errmsg ) ;
2009-04-25 14:16:32 +00:00
}
2008-03-18 22:13:32 +00:00
2009-11-25 00:23:07 +00:00
switch_cache_db_release_db_handle ( & dbh ) ;
2008-03-18 22:13:32 +00:00
2009-04-25 14:16:32 +00:00
switch_mutex_init ( & profile - > mutex , SWITCH_MUTEX_NESTED , profile - > pool ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Added Profile %s \n " , profile - > name ) ;
switch_core_hash_insert ( globals . profile_hash , profile - > name , profile ) ;
}
2008-03-18 22:13:32 +00:00
2009-04-25 14:16:32 +00:00
end :
2009-12-10 21:04:33 +00:00
2009-11-26 06:59:57 +00:00
switch_cache_db_release_db_handle ( & dbh ) ;
2009-12-10 21:04:33 +00:00
2009-04-25 14:16:32 +00:00
if ( xml ) {
switch_xml_free ( xml ) ;
}
2009-10-28 21:32:20 +00:00
if ( event ) {
switch_event_destroy ( & event ) ;
}
2009-04-25 14:16:32 +00:00
return profile ;
}
2009-02-28 03:56:38 +00:00
2007-11-29 01:05:05 +00:00
2010-02-06 03:38:24 +00:00
static vm_profile_t * get_profile ( const char * profile_name )
2009-04-25 14:16:32 +00:00
{
2009-06-20 03:29:43 +00:00
vm_profile_t * profile = NULL ;
2007-12-26 17:37:13 +00:00
2009-04-25 14:16:32 +00:00
switch_mutex_lock ( globals . mutex ) ;
if ( ! ( profile = switch_core_hash_find ( globals . profile_hash , profile_name ) ) ) {
2010-02-06 03:38:24 +00:00
profile = load_profile ( profile_name ) ;
2009-04-25 14:16:32 +00:00
}
if ( profile ) {
2010-03-08 18:25:43 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG10 , " [%s] rwlock \n " , profile - > name ) ;
2010-02-06 03:38:24 +00:00
2009-04-25 14:16:32 +00:00
switch_thread_rwlock_rdlock ( profile - > rwlock ) ;
}
switch_mutex_unlock ( globals . mutex ) ;
return profile ;
}
2009-06-20 19:55:30 +00:00
static void profile_rwunlock ( vm_profile_t * profile )
{
switch_thread_rwlock_unlock ( profile - > rwlock ) ;
if ( switch_test_flag ( profile , PFLAG_DESTROY ) ) {
2010-02-15 20:34:11 +00:00
if ( switch_thread_rwlock_trywrlock ( profile - > rwlock ) = = SWITCH_STATUS_SUCCESS ) {
switch_thread_rwlock_unlock ( profile - > rwlock ) ;
2009-06-20 19:55:30 +00:00
free_profile ( profile ) ;
}
}
}
2009-04-25 14:16:32 +00:00
static switch_status_t load_config ( void )
{
switch_xml_t cfg , xml , settings , param , x_profiles , x_profile ;
if ( ! ( xml = switch_xml_open_cfg ( global_cf , & cfg , NULL ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Open of %s failed \n " , global_cf ) ;
return SWITCH_STATUS_TERM ;
}
switch_mutex_lock ( globals . mutex ) ;
if ( ( settings = switch_xml_child ( cfg , " settings " ) ) ) {
for ( param = switch_xml_child ( settings , " param " ) ; param ; param = param - > next ) {
char * var = ( char * ) switch_xml_attr_soft ( param , " name " ) ;
char * val = ( char * ) switch_xml_attr_soft ( param , " value " ) ;
if ( ! strcasecmp ( var , " debug " ) ) {
globals . debug = atoi ( val ) ;
} else if ( ! strcasecmp ( var , " message-query-exact-match " ) ) {
globals . message_query_exact_match = switch_true ( val ) ;
}
2007-12-26 17:37:13 +00:00
}
}
2009-04-25 14:16:32 +00:00
if ( ( x_profiles = switch_xml_child ( cfg , " profiles " ) ) ) {
for ( x_profile = switch_xml_child ( x_profiles , " profile " ) ; x_profile ; x_profile = x_profile - > next ) {
load_profile ( switch_xml_attr_soft ( x_profile , " name " ) ) ;
}
}
2009-06-20 03:29:43 +00:00
switch_mutex_unlock ( globals . mutex ) ;
2009-04-25 14:16:32 +00:00
2007-10-12 03:28:59 +00:00
switch_xml_free ( xml ) ;
return SWITCH_STATUS_SUCCESS ;
}
static switch_status_t cancel_on_dtmf ( switch_core_session_t * session , void * input , switch_input_type_t itype , void * buf , unsigned int buflen )
{
switch ( itype ) {
case SWITCH_INPUT_TYPE_DTMF :
2007-12-26 17:37:13 +00:00
{
switch_dtmf_t * dtmf = ( switch_dtmf_t * ) input ;
if ( buf & & buflen ) {
char * bp = ( char * ) buf ;
bp [ 0 ] = dtmf - > digit ;
bp [ 1 ] = ' \0 ' ;
}
return SWITCH_STATUS_BREAK ;
}
2007-10-12 03:28:59 +00:00
break ;
default :
break ;
}
return SWITCH_STATUS_SUCCESS ;
}
2007-10-12 22:08:30 +00:00
struct call_control {
2007-12-26 17:37:13 +00:00
vm_profile_t * profile ;
switch_file_handle_t * fh ;
char buf [ 4 ] ;
int noexit ;
2007-10-12 22:08:30 +00:00
} ;
typedef struct call_control cc_t ;
2007-10-12 03:28:59 +00:00
static switch_status_t control_playback ( switch_core_session_t * session , void * input , switch_input_type_t itype , void * buf , unsigned int buflen )
{
switch ( itype ) {
case SWITCH_INPUT_TYPE_DTMF :
2007-12-26 17:37:13 +00:00
{
switch_dtmf_t * dtmf = ( switch_dtmf_t * ) input ;
cc_t * cc = ( cc_t * ) buf ;
switch_file_handle_t * fh = cc - > fh ;
uint32_t pos = 0 ;
2008-05-27 04:54:52 +00:00
if ( ! cc - > noexit
& & ( dtmf - > digit = = * cc - > profile - > delete_file_key | | dtmf - > digit = = * cc - > profile - > save_file_key
2009-07-27 20:46:05 +00:00
| | dtmf - > digit = = * cc - > profile - > prev_msg_key | | dtmf - > digit = = * cc - > profile - > next_msg_key
| | dtmf - > digit = = * cc - > profile - > terminator_key | | dtmf - > digit = = * cc - > profile - > skip_info_key ) ) {
2007-12-26 17:37:13 +00:00
* cc - > buf = dtmf - > digit ;
return SWITCH_STATUS_BREAK ;
}
if ( ! ( fh & & fh - > file_interface & & switch_test_flag ( fh , SWITCH_FILE_OPEN ) ) ) {
return SWITCH_STATUS_SUCCESS ;
}
if ( dtmf - > digit = = * cc - > profile - > pause_key ) {
if ( switch_test_flag ( fh , SWITCH_FILE_PAUSE ) ) {
switch_clear_flag ( fh , SWITCH_FILE_PAUSE ) ;
} else {
switch_set_flag ( fh , SWITCH_FILE_PAUSE ) ;
}
return SWITCH_STATUS_SUCCESS ;
}
if ( dtmf - > digit = = * cc - > profile - > restart_key ) {
unsigned int seekpos = 0 ;
fh - > speed = 0 ;
switch_core_file_seek ( fh , & seekpos , 0 , SEEK_SET ) ;
return SWITCH_STATUS_SUCCESS ;
}
if ( dtmf - > digit = = * cc - > profile - > ff_key ) {
2009-08-01 05:35:22 +00:00
int samps = 24000 ;
2007-12-26 17:37:13 +00:00
switch_core_file_seek ( fh , & pos , samps , SEEK_CUR ) ;
return SWITCH_STATUS_SUCCESS ;
}
if ( dtmf - > digit = = * cc - > profile - > rew_key ) {
2009-08-01 05:35:22 +00:00
int samps = - 48000 ;
switch_core_file_seek ( fh , & pos , samps , SEEK_CUR ) ;
2007-12-26 17:37:13 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2009-07-27 18:44:30 +00:00
if ( ! cc - > noexit & & dtmf - > digit = = * cc - > profile - > terminator_key ) {
* cc - > buf = dtmf - > digit ;
return SWITCH_STATUS_BREAK ;
}
2007-12-26 17:37:13 +00:00
}
2007-10-12 03:28:59 +00:00
break ;
default :
break ;
2008-05-27 04:54:52 +00:00
}
2007-10-12 03:28:59 +00:00
return SWITCH_STATUS_SUCCESS ;
}
struct prefs_callback {
2007-12-26 17:37:13 +00:00
char name_path [ 255 ] ;
char greeting_path [ 255 ] ;
2008-08-20 22:06:04 +00:00
char password [ 255 ] ;
2007-10-12 03:28:59 +00:00
} ;
typedef struct prefs_callback prefs_callback_t ;
static int prefs_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
prefs_callback_t * cbt = ( prefs_callback_t * ) pArg ;
switch_copy_string ( cbt - > name_path , argv [ 2 ] , sizeof ( cbt - > name_path ) ) ;
switch_copy_string ( cbt - > greeting_path , argv [ 3 ] , sizeof ( cbt - > greeting_path ) ) ;
2008-08-20 22:06:04 +00:00
switch_copy_string ( cbt - > password , argv [ 4 ] , sizeof ( cbt - > password ) ) ;
2010-02-06 03:38:24 +00:00
2007-10-12 03:28:59 +00:00
return 0 ;
}
typedef enum {
2007-12-26 17:37:13 +00:00
VM_CHECK_START ,
VM_CHECK_AUTH ,
VM_CHECK_MENU ,
VM_CHECK_CONFIG ,
VM_CHECK_PLAY_MESSAGES ,
VM_CHECK_FOLDER_SUMMARY ,
VM_CHECK_LISTEN
2007-10-12 03:28:59 +00:00
} vm_check_state_t ;
2008-09-08 21:56:07 +00:00
# define VM_INVALID_EXTENSION_MACRO "voicemail_invalid_extension"
# define VM_FORWARD_MESSAGE_ENTER_EXTENSION_MACRO "voicemail_forward_message_enter_extension"
2007-10-12 03:28:59 +00:00
# define VM_ACK_MACRO "voicemail_ack"
# define VM_SAY_DATE_MACRO "voicemail_say_date"
# define VM_PLAY_GREETING_MACRO "voicemail_play_greeting"
# define VM_SAY_MESSAGE_NUMBER_MACRO "voicemail_say_message_number"
# define VM_SAY_NUMBER_MACRO "voicemail_say_number"
# define VM_SAY_PHONE_NUMBER_MACRO "voicemail_say_phone_number"
# define VM_SAY_NAME_MACRO "voicemail_say_name"
2008-09-08 21:56:07 +00:00
# define VM_FORWARD_PREPEND_MACRO "voicemail_forward_prepend"
2007-10-12 03:28:59 +00:00
# define VM_RECORD_MESSAGE_MACRO "voicemail_record_message"
# define VM_CHOOSE_GREETING_MACRO "voicemail_choose_greeting"
# define VM_CHOOSE_GREETING_FAIL_MACRO "voicemail_choose_greeting_fail"
# define VM_CHOOSE_GREETING_SELECTED_MACRO "voicemail_greeting_selected"
# define VM_RECORD_GREETING_MACRO "voicemail_record_greeting"
# define VM_RECORD_NAME_MACRO "voicemail_record_name"
# define VM_LISTEN_FILE_CHECK_MACRO "voicemail_listen_file_check"
# define VM_RECORD_FILE_CHECK_MACRO "voicemail_record_file_check"
2007-10-12 22:08:30 +00:00
# define VM_RECORD_URGENT_CHECK_MACRO "voicemail_record_urgent_check"
2007-10-12 03:28:59 +00:00
# define VM_MENU_MACRO "voicemail_menu"
# define VM_CONFIG_MENU_MACRO "voicemail_config_menu"
# define VM_ENTER_ID_MACRO "voicemail_enter_id"
# define VM_ENTER_PASS_MACRO "voicemail_enter_pass"
# define VM_FAIL_AUTH_MACRO "voicemail_fail_auth"
# define VM_ABORT_MACRO "voicemail_abort"
# define VM_HELLO_MACRO "voicemail_hello"
# define VM_GOODBYE_MACRO "voicemail_goodbye"
2007-10-12 22:08:30 +00:00
# define VM_MESSAGE_COUNT_MACRO "voicemail_message_count"
2009-05-14 22:47:44 +00:00
# define VM_DISK_QUOTA_EXCEEDED_MACRO "voicemail_disk_quota_exceeded"
2007-10-13 00:22:13 +00:00
# define URGENT_FLAG_STRING "A_URGENT"
# define NORMAL_FLAG_STRING "B_NORMAL"
2007-10-12 03:28:59 +00:00
static switch_status_t vm_macro_get ( switch_core_session_t * session ,
2007-12-26 17:37:13 +00:00
char * macro ,
char * macro_arg ,
2008-05-27 04:54:52 +00:00
char * buf , switch_size_t buflen , switch_size_t maxlen , char * term_chars , char * terminator_key , uint32_t timeout )
2007-10-12 03:28:59 +00:00
{
2007-12-26 17:37:13 +00:00
switch_input_args_t args = { 0 } , * ap = NULL ;
switch_status_t status = SWITCH_STATUS_SUCCESS ;
switch_size_t bslen ;
if ( buf & & buflen ) {
memset ( buf , 0 , buflen ) ;
args . input_callback = cancel_on_dtmf ;
args . buf = buf ;
2008-05-27 04:54:52 +00:00
args . buflen = ( uint32_t ) buflen ;
2007-12-26 17:37:13 +00:00
ap = & args ;
}
status = switch_ivr_phrase_macro ( session , macro , macro_arg , NULL , ap ) ;
if ( status ! = SWITCH_STATUS_SUCCESS & & status ! = SWITCH_STATUS_BREAK ) {
if ( buf ) {
memset ( buf , 0 , buflen ) ;
}
return status ;
}
if ( ! buf ) {
return status ;
}
bslen = strlen ( buf ) ;
if ( maxlen = = 0 | | maxlen > buflen - 1 ) {
2008-05-27 04:54:52 +00:00
maxlen = buflen - 1 ;
2007-12-26 17:37:13 +00:00
}
2008-09-09 18:24:13 +00:00
2007-12-26 17:37:13 +00:00
if ( bslen < maxlen ) {
2008-01-07 16:49:46 +00:00
status = switch_ivr_collect_digits_count ( session , buf + bslen , buflen , maxlen - bslen , term_chars , terminator_key , timeout , 0 , 0 ) ;
2008-09-09 18:24:13 +00:00
if ( status = = SWITCH_STATUS_TIMEOUT ) {
status = SWITCH_STATUS_SUCCESS ;
}
2007-12-26 17:37:13 +00:00
}
return status ;
2007-10-12 03:28:59 +00:00
}
struct callback {
2007-12-26 17:37:13 +00:00
char * buf ;
size_t len ;
int matches ;
2007-10-12 03:28:59 +00:00
} ;
typedef struct callback callback_t ;
2009-11-23 22:46:34 +00:00
struct msg_cnt_callback {
char * buf ;
size_t len ;
int matches ;
int total_new_messages ;
int total_new_urgent_messages ;
int total_saved_messages ;
int total_saved_urgent_messages ;
} ;
typedef struct msg_cnt_callback msg_cnt_callback_t ;
static int message_count_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
msg_cnt_callback_t * cbt = ( msg_cnt_callback_t * ) pArg ;
2010-02-06 03:38:24 +00:00
if ( atoi ( argv [ 0 ] ) = = 1 ) { /* UnRead */
if ( ! strcasecmp ( argv [ 1 ] , " A_URGENT " ) ) { /* Urgent */
2009-11-23 22:46:34 +00:00
cbt - > total_new_urgent_messages = atoi ( argv [ 2 ] ) ;
2010-02-06 03:38:24 +00:00
} else { /* Normal */
2009-11-23 22:46:34 +00:00
cbt - > total_new_messages = atoi ( argv [ 2 ] ) ;
}
2010-02-06 03:38:24 +00:00
} else { /* Already Read */
if ( ! strcasecmp ( argv [ 1 ] , " A_URGENT " ) ) { /* Urgent */
2009-11-23 22:46:34 +00:00
cbt - > total_saved_urgent_messages = atoi ( argv [ 2 ] ) ;
2010-02-06 03:38:24 +00:00
} else { /* Normal */
2009-11-23 22:46:34 +00:00
cbt - > total_saved_messages = atoi ( argv [ 2 ] ) ;
}
}
return 0 ;
}
2007-10-12 03:28:59 +00:00
static int sql2str_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
callback_t * cbt = ( callback_t * ) pArg ;
switch_copy_string ( cbt - > buf , argv [ 0 ] , cbt - > len ) ;
cbt - > matches + + ;
return 0 ;
}
static int unlink_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
2007-12-26 17:37:13 +00:00
if ( argv [ 0 ] ) {
2007-12-15 04:58:44 +00:00
if ( unlink ( argv [ 0 ] ) ! = 0 ) {
2008-10-11 06:19:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Failed to delete file [%s] \n " , argv [ 0 ] ) ;
2007-12-15 04:58:44 +00:00
}
2007-12-26 17:37:13 +00:00
}
2007-10-12 03:28:59 +00:00
return 0 ;
}
typedef enum {
2007-12-26 17:37:13 +00:00
MSG_NONE ,
MSG_NEW ,
MSG_SAVED
2007-10-12 03:28:59 +00:00
} msg_type_t ;
2008-07-17 19:46:25 +00:00
switch_status_t measure_file_len ( const char * path , switch_size_t * message_len )
{
2010-02-06 03:38:24 +00:00
2008-07-17 19:46:25 +00:00
switch_file_handle_t fh = { 0 } ;
uint32_t pos = 0 ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2010-02-06 03:38:24 +00:00
if ( switch_core_file_open ( & fh , path , 0 , 0 , SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT , NULL ) = = SWITCH_STATUS_SUCCESS ) {
2008-07-17 19:46:25 +00:00
if ( switch_core_file_seek ( & fh , & pos , 0 , SEEK_END ) = = SWITCH_STATUS_SUCCESS ) {
2009-04-23 00:30:43 +00:00
* message_len = pos / fh . samplerate ;
2008-07-17 19:46:25 +00:00
status = SWITCH_STATUS_SUCCESS ;
}
switch_core_file_close ( & fh ) ;
}
2010-02-06 03:38:24 +00:00
2008-07-17 19:46:25 +00:00
return status ;
}
2008-05-27 04:54:52 +00:00
static switch_status_t create_file ( switch_core_session_t * session , vm_profile_t * profile ,
2008-11-26 21:04:21 +00:00
char * macro_name , char * file_path , switch_size_t * message_len , switch_bool_t limit ,
const char * exit_keys , char * key_pressed )
2007-10-12 03:28:59 +00:00
{
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-12-26 17:37:13 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
switch_file_handle_t fh = { 0 } ;
switch_input_args_t args = { 0 } ;
char term ;
2008-05-27 04:54:52 +00:00
char input [ 10 ] = " " , key_buf [ 80 ] = " " ;
2007-12-26 17:37:13 +00:00
cc_t cc = { 0 } ;
2010-02-06 03:38:24 +00:00
switch_codec_implementation_t read_impl = { 0 } ;
2009-04-02 16:01:51 +00:00
int got_file = 0 ;
2010-02-06 03:38:24 +00:00
switch_core_session_get_read_impl ( session , & read_impl ) ;
2007-12-26 17:37:13 +00:00
2008-11-26 21:04:21 +00:00
if ( exit_keys ) {
* key_pressed = ' \0 ' ;
}
2008-05-27 04:54:52 +00:00
while ( switch_channel_ready ( channel ) ) {
2009-02-26 20:46:08 +00:00
uint32_t counter = 0 ;
2008-05-27 04:54:52 +00:00
switch_snprintf ( key_buf , sizeof ( key_buf ) , " %s:%s:%s " , profile - > listen_file_key , profile - > save_file_key , profile - > record_file_key ) ;
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
record_file :
* message_len = 0 ;
2008-11-26 21:04:21 +00:00
2010-02-06 03:38:24 +00:00
if ( macro_name )
TRY_CODE ( switch_ivr_phrase_macro ( session , macro_name , NULL , NULL , NULL ) ) ;
2009-07-27 17:06:39 +00:00
switch_channel_flush_dtmf ( channel ) ;
2007-12-26 17:37:13 +00:00
TRY_CODE ( switch_ivr_gentones ( session , profile - > tone_spec , 0 , NULL ) ) ;
memset ( & fh , 0 , sizeof ( fh ) ) ;
fh . thresh = profile - > record_threshold ;
fh . silence_hits = profile - > record_silence_hits ;
fh . samplerate = profile - > record_sample_rate ;
2008-11-26 21:04:21 +00:00
memset ( input , 0 , sizeof ( input ) ) ;
args . input_callback = cancel_on_dtmf ;
args . buf = input ;
args . buflen = sizeof ( input ) ;
2007-12-26 17:37:13 +00:00
switch_ivr_record_file ( session , & fh , file_path , & args , profile - > max_record_len ) ;
2008-11-26 21:04:21 +00:00
2009-04-02 16:01:51 +00:00
if ( switch_file_exists ( file_path , switch_core_session_get_pool ( session ) ) = = SWITCH_STATUS_SUCCESS ) {
got_file = 1 ;
}
2009-11-12 03:38:26 +00:00
if ( limit & & ( * message_len = fh . samples_out / ( fh . samplerate ? fh . samplerate : 8000 ) ) < profile - > min_record_len ) {
2008-01-04 01:49:26 +00:00
if ( unlink ( file_path ) ! = 0 ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Failed to delete file [%s] \n " , file_path ) ;
2008-01-04 01:49:26 +00:00
}
2009-04-02 16:01:51 +00:00
got_file = 0 ;
2008-11-26 21:04:21 +00:00
if ( exit_keys & & input [ 0 ] & & strchr ( exit_keys , input [ 0 ] ) ) {
* key_pressed = input [ 0 ] ;
return SWITCH_STATUS_SUCCESS ;
}
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Message is less than minimum record length: %d, discarding it. \n " ,
2008-11-26 21:04:21 +00:00
profile - > min_record_len ) ;
2009-02-26 20:46:08 +00:00
if ( switch_channel_ready ( channel ) & & counter < profile - > max_retries ) {
2008-09-22 17:35:22 +00:00
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_ACK_MACRO , " too-small " , NULL , NULL ) ) ;
2009-02-26 20:46:08 +00:00
counter + + ;
2008-05-27 04:54:52 +00:00
goto record_file ;
} else {
2008-09-23 20:31:49 +00:00
status = SWITCH_STATUS_NOTFOUND ;
2008-05-27 04:54:52 +00:00
goto end ;
}
} else {
status = SWITCH_STATUS_SUCCESS ;
}
2008-10-01 18:37:55 +00:00
2008-10-01 13:06:59 +00:00
if ( profile - > auto_playback_recordings ) {
2010-02-06 03:38:24 +00:00
play_file :
2008-10-01 13:06:59 +00:00
memset ( & fh , 0 , sizeof ( fh ) ) ;
args . input_callback = control_playback ;
memset ( & cc , 0 , sizeof ( cc ) ) ;
cc . profile = profile ;
cc . fh = & fh ;
args . buf = & cc ;
switch_ivr_play_file ( session , & fh , file_path , & args ) ;
}
2008-05-27 04:54:52 +00:00
while ( switch_channel_ready ( channel ) ) {
2008-09-08 21:56:07 +00:00
* input = ' \0 ' ;
2008-09-24 20:29:35 +00:00
if ( * cc . buf & & * cc . buf ! = * profile - > terminator_key ) {
* input = * cc . buf ;
* ( input + 1 ) = ' \0 ' ;
status = SWITCH_STATUS_SUCCESS ;
* cc . buf = ' \0 ' ;
} else {
2010-02-06 03:38:24 +00:00
( void ) vm_macro_get ( session , VM_RECORD_FILE_CHECK_MACRO , key_buf , input , sizeof ( input ) , 1 , " " , & term , profile - > digit_timeout ) ;
2008-09-24 20:29:35 +00:00
}
2007-12-26 17:37:13 +00:00
if ( ! strcmp ( input , profile - > listen_file_key ) ) {
goto play_file ;
} else if ( ! strcmp ( input , profile - > record_file_key ) ) {
goto record_file ;
} else {
2010-02-06 03:38:24 +00:00
( void ) switch_ivr_phrase_macro ( session , VM_ACK_MACRO , " saved " , NULL , NULL ) ;
2007-12-26 17:37:13 +00:00
goto end ;
}
}
}
2008-05-27 04:54:52 +00:00
end :
2009-04-02 16:01:51 +00:00
if ( ! got_file ) {
status = SWITCH_STATUS_NOTFOUND ;
}
2007-12-26 17:37:13 +00:00
return status ;
2007-10-12 03:28:59 +00:00
}
struct listen_callback {
2007-12-26 17:37:13 +00:00
char created_epoch [ 255 ] ;
char read_epoch [ 255 ] ;
char user [ 255 ] ;
char domain [ 255 ] ;
char uuid [ 255 ] ;
char cid_name [ 255 ] ;
char cid_number [ 255 ] ;
char in_folder [ 255 ] ;
char file_path [ 255 ] ;
char message_len [ 255 ] ;
char flags [ 255 ] ;
char read_flags [ 255 ] ;
2010-01-13 01:32:01 +00:00
char forwarded_by [ 255 ] ;
2007-12-26 17:37:13 +00:00
char * email ;
int index ;
int want ;
msg_type_t type ;
2010-02-06 03:38:24 +00:00
msg_move_t move ;
2009-10-01 22:43:44 +00:00
char * convert_cmd ;
char * convert_ext ;
2007-10-12 03:28:59 +00:00
} ;
typedef struct listen_callback listen_callback_t ;
static int listen_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
listen_callback_t * cbt = ( listen_callback_t * ) pArg ;
2007-12-26 17:37:13 +00:00
if ( cbt - > index + + ! = cbt - > want ) {
return 0 ;
}
2007-10-12 03:28:59 +00:00
2007-12-26 17:37:13 +00:00
switch_copy_string ( cbt - > created_epoch , argv [ 0 ] , 255 ) ;
2007-10-12 03:28:59 +00:00
switch_copy_string ( cbt - > read_epoch , argv [ 1 ] , 255 ) ;
switch_copy_string ( cbt - > user , argv [ 2 ] , 255 ) ;
switch_copy_string ( cbt - > domain , argv [ 3 ] , 255 ) ;
switch_copy_string ( cbt - > uuid , argv [ 4 ] , 255 ) ;
switch_copy_string ( cbt - > cid_name , argv [ 5 ] , 255 ) ;
switch_copy_string ( cbt - > cid_number , argv [ 6 ] , 255 ) ;
switch_copy_string ( cbt - > in_folder , argv [ 7 ] , 255 ) ;
switch_copy_string ( cbt - > file_path , argv [ 8 ] , 255 ) ;
2007-11-26 23:41:00 +00:00
switch_copy_string ( cbt - > message_len , argv [ 9 ] , 255 ) ;
switch_copy_string ( cbt - > flags , argv [ 10 ] , 255 ) ;
switch_copy_string ( cbt - > read_flags , argv [ 11 ] , 255 ) ;
2010-01-13 01:32:01 +00:00
switch_copy_string ( cbt - > forwarded_by , argv [ 12 ] , 255 ) ;
2007-12-15 04:58:44 +00:00
2007-10-12 03:28:59 +00:00
return - 1 ;
}
2009-05-18 17:34:35 +00:00
static char * resolve_id ( const char * myid , const char * domain_name , const char * action )
2009-05-18 17:06:13 +00:00
{
switch_xml_t xx_user , xx_domain , xx_domain_root ;
switch_event_t * params ;
2009-05-18 17:34:35 +00:00
char * ret = ( char * ) myid ;
2009-05-18 17:06:13 +00:00
switch_event_create ( & params , SWITCH_EVENT_GENERAL ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " action " , action ) ;
2010-02-06 03:38:24 +00:00
if ( switch_xml_locate_user ( " id " , myid , domain_name , NULL , & xx_domain_root , & xx_domain , & xx_user , NULL , params ) = = SWITCH_STATUS_SUCCESS ) {
2009-05-18 17:34:35 +00:00
ret = strdup ( switch_xml_attr ( xx_user , " id " ) ) ;
2009-05-18 17:06:13 +00:00
switch_xml_free ( xx_domain_root ) ;
}
2010-02-06 03:38:24 +00:00
2009-05-18 17:06:13 +00:00
switch_event_destroy ( & params ) ;
2009-05-18 17:34:35 +00:00
return ret ;
2009-05-18 17:06:13 +00:00
}
2007-10-12 03:28:59 +00:00
2010-02-06 03:38:24 +00:00
static void message_count ( vm_profile_t * profile , const char * id_in , const char * domain_name , const char * myfolder , int * total_new_messages ,
int * total_saved_messages , int * total_new_urgent_messages , int * total_saved_urgent_messages )
2007-10-23 14:45:22 +00:00
{
2007-12-26 17:37:13 +00:00
char msg_count [ 80 ] = " " ;
2009-11-23 22:46:34 +00:00
msg_cnt_callback_t cbt = { 0 } ;
2007-12-26 17:37:13 +00:00
char sql [ 256 ] ;
2009-05-27 02:18:56 +00:00
char * myid = NULL ;
2007-12-26 17:37:13 +00:00
2009-11-23 22:46:34 +00:00
2007-12-26 17:37:13 +00:00
cbt . buf = msg_count ;
cbt . len = sizeof ( msg_count ) ;
2009-11-23 22:46:34 +00:00
cbt . total_new_messages = 0 ;
cbt . total_new_urgent_messages = 0 ;
cbt . total_saved_messages = 0 ;
cbt . total_saved_urgent_messages = 0 ;
2009-05-18 17:34:35 +00:00
myid = resolve_id ( id_in , domain_name , " message-count " ) ;
2007-10-23 14:45:22 +00:00
2008-05-27 04:54:52 +00:00
switch_snprintf ( sql , sizeof ( sql ) ,
2009-11-23 22:46:34 +00:00
" select read_epoch=0, read_flags, count(read_epoch) from voicemail_msgs where username='%s' and domain='%s' and in_folder='%s' group by read_epoch=0,read_flags; " ,
2010-02-06 03:38:24 +00:00
myid , domain_name , myfolder ) ;
2007-12-26 17:37:13 +00:00
2009-11-23 22:46:34 +00:00
vm_execute_sql_callback ( profile , profile - > mutex , sql , message_count_callback , & cbt ) ;
2007-12-26 17:37:13 +00:00
2009-11-25 18:26:49 +00:00
* total_new_messages = cbt . total_new_messages + cbt . total_new_urgent_messages ;
2009-11-23 22:46:34 +00:00
* total_new_urgent_messages = cbt . total_new_urgent_messages ;
2009-11-25 18:26:49 +00:00
* total_saved_messages = cbt . total_saved_messages + cbt . total_saved_urgent_messages ;
2009-11-23 22:46:34 +00:00
* total_saved_urgent_messages = cbt . total_saved_urgent_messages ;
2009-05-18 17:34:35 +00:00
if ( myid ! = id_in ) {
free ( myid ) ;
}
2007-10-23 14:45:22 +00:00
}
2008-09-08 21:56:07 +00:00
# define VM_STARTSAMPLES 1024 * 32
static char * vm_merge_file ( switch_core_session_t * session , vm_profile_t * profile , const char * announce , const char * orig )
{
2010-02-06 03:38:24 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
switch_file_handle_t lrfh = { 0 } , * rfh = NULL , lfh = {
0 } , * fh = NULL ;
2008-09-08 21:56:07 +00:00
char * tmp_path ;
switch_uuid_t uuid ;
char uuid_str [ SWITCH_UUID_FORMATTED_LENGTH + 1 ] ;
char * ret = NULL ;
int16_t * abuf = NULL ;
switch_size_t olen = 0 ;
int asis = 0 ;
2010-02-06 03:38:24 +00:00
switch_codec_implementation_t read_impl = { 0 } ;
switch_core_session_get_read_impl ( session , & read_impl ) ;
2008-09-08 21:56:07 +00:00
switch_uuid_get ( & uuid ) ;
switch_uuid_format ( uuid_str , & uuid ) ;
2009-02-10 19:09:06 +00:00
lfh . channels = read_impl . number_of_channels ;
lfh . native_rate = read_impl . actual_samples_per_second ;
2008-09-08 21:56:07 +00:00
tmp_path = switch_core_session_sprintf ( session , " %s%smsg_%s.%s " , SWITCH_GLOBAL_dirs . temp_dir , SWITCH_PATH_SEPARATOR , uuid_str , profile - > file_ext ) ;
if ( switch_core_file_open ( & lfh ,
tmp_path ,
lfh . channels ,
2010-02-06 03:38:24 +00:00
read_impl . actual_samples_per_second , SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Failed to open file %s \n " , tmp_path ) ;
2008-09-08 21:56:07 +00:00
goto end ;
}
fh = & lfh ;
2010-02-06 03:38:24 +00:00
2008-09-08 21:56:07 +00:00
if ( switch_core_file_open ( & lrfh ,
announce ,
lfh . channels ,
2010-02-06 03:38:24 +00:00
read_impl . actual_samples_per_second , SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Failed to open file %s \n " , announce ) ;
2008-09-08 21:56:07 +00:00
goto end ;
}
rfh = & lrfh ;
switch_zmalloc ( abuf , VM_STARTSAMPLES * sizeof ( * abuf ) ) ;
if ( switch_test_flag ( fh , SWITCH_FILE_NATIVE ) ) {
asis = 1 ;
2010-02-06 03:38:24 +00:00
}
2008-09-08 21:56:07 +00:00
while ( switch_channel_ready ( channel ) ) {
olen = VM_STARTSAMPLES ;
if ( ! asis ) {
olen / = 2 ;
}
if ( switch_core_file_read ( rfh , abuf , & olen ) ! = SWITCH_STATUS_SUCCESS | | ! olen ) {
break ;
}
2010-02-06 03:38:24 +00:00
2008-09-08 21:56:07 +00:00
switch_core_file_write ( fh , abuf , & olen ) ;
}
if ( rfh ) {
switch_core_file_close ( rfh ) ;
rfh = NULL ;
}
if ( switch_core_file_open ( & lrfh ,
orig ,
lfh . channels ,
2010-02-06 03:38:24 +00:00
read_impl . actual_samples_per_second , SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Failed to open file %s \n " , orig ) ;
2008-09-08 21:56:07 +00:00
goto end ;
}
rfh = & lrfh ;
while ( switch_channel_ready ( channel ) ) {
olen = VM_STARTSAMPLES ;
if ( ! asis ) {
olen / = 2 ;
}
if ( switch_core_file_read ( rfh , abuf , & olen ) ! = SWITCH_STATUS_SUCCESS | | ! olen ) {
break ;
}
2010-02-06 03:38:24 +00:00
2008-09-08 21:56:07 +00:00
switch_core_file_write ( fh , abuf , & olen ) ;
}
2008-09-12 15:29:53 +00:00
if ( unlink ( announce ) ! = 0 ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Failed to delete file [%s] \n " , announce ) ;
2008-09-12 15:29:53 +00:00
}
2008-09-08 21:56:07 +00:00
ret = tmp_path ;
2010-02-06 03:38:24 +00:00
2009-01-14 00:02:15 +00:00
end :
2008-09-08 21:56:07 +00:00
if ( fh ) {
switch_core_file_close ( fh ) ;
fh = NULL ;
}
if ( rfh ) {
switch_core_file_close ( rfh ) ;
rfh = NULL ;
}
switch_safe_free ( abuf ) ;
return ret ;
}
2007-10-23 14:45:22 +00:00
2007-10-12 03:28:59 +00:00
static switch_status_t listen_file ( switch_core_session_t * session , vm_profile_t * profile , listen_callback_t * cbt )
{
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-12-26 17:37:13 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
switch_input_args_t args = { 0 } ;
char term ;
2008-05-27 04:54:52 +00:00
char input [ 10 ] = " " , key_buf [ 80 ] = " " ;
2007-12-26 17:37:13 +00:00
switch_file_handle_t fh = { 0 } ;
cc_t cc = { 0 } ;
2010-02-06 03:38:24 +00:00
char * forward_file_path = NULL ;
2008-09-08 21:56:07 +00:00
2007-10-12 03:28:59 +00:00
2008-02-15 23:23:59 +00:00
if ( switch_channel_ready ( channel ) ) {
2007-12-26 17:37:13 +00:00
args . input_callback = cancel_on_dtmf ;
2007-10-12 03:28:59 +00:00
2010-02-06 03:38:24 +00:00
switch_snprintf ( key_buf , sizeof ( key_buf ) , " %s:%s:%s:%s:%s:%s%s%s " , profile - > listen_file_key , profile - > save_file_key ,
profile - > delete_file_key , profile - > email_key , profile - > callback_key ,
2009-11-25 00:23:07 +00:00
profile - > forward_key , cbt - > email ? " : " : " " , cbt - > email ? cbt - > email : " " ) ;
2010-02-06 03:38:24 +00:00
2007-10-12 03:28:59 +00:00
2008-05-27 04:54:52 +00:00
switch_snprintf ( input , sizeof ( input ) , " %s:%d " , cbt - > type = = MSG_NEW ? " new " : " saved " , cbt - > want + 1 ) ;
2007-12-26 17:37:13 +00:00
memset ( & cc , 0 , sizeof ( cc ) ) ;
cc . profile = profile ;
args . buf = & cc ;
args . input_callback = control_playback ;
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_SAY_MESSAGE_NUMBER_MACRO , input , NULL , & args ) ) ;
2008-09-27 20:34:47 +00:00
play_file :
if ( ! * cc . buf & & ( profile - > play_date_announcement = = VM_DATE_FIRST ) ) {
cc . fh = NULL ;
2007-12-26 17:37:13 +00:00
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_SAY_DATE_MACRO , cbt - > created_epoch , NULL , & args ) ) ;
}
2009-07-27 20:46:05 +00:00
if ( ! * cc . buf | | * cc . buf = = * cc . profile - > skip_info_key ) {
* cc . buf = ' \0 ' ;
2007-12-26 17:37:13 +00:00
memset ( & fh , 0 , sizeof ( fh ) ) ;
cc . fh = & fh ;
2009-07-01 17:04:15 +00:00
TRY_CODE ( switch_ivr_play_file ( session , & fh , cbt - > file_path , & args ) ) ;
2007-12-26 17:37:13 +00:00
}
2008-09-27 20:34:47 +00:00
if ( ! * cc . buf & & ( profile - > play_date_announcement = = VM_DATE_LAST ) ) {
cc . fh = NULL ;
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_SAY_DATE_MACRO , cbt - > created_epoch , NULL , & args ) ) ;
}
2007-12-26 17:37:13 +00:00
if ( switch_channel_ready ( channel ) ) {
2008-09-24 20:29:35 +00:00
if ( * cc . buf & & * cc . buf ! = * profile - > terminator_key ) {
* input = * cc . buf ;
* ( input + 1 ) = ' \0 ' ;
status = SWITCH_STATUS_SUCCESS ;
* cc . buf = ' \0 ' ;
} else {
TRY_CODE ( vm_macro_get ( session , VM_LISTEN_FILE_CHECK_MACRO , key_buf , input , sizeof ( input ) , 1 , " " , & term , profile - > digit_timeout ) ) ;
}
2009-07-27 18:44:30 +00:00
if ( ! strcmp ( input , profile - > prev_msg_key ) ) {
cbt - > move = VM_MOVE_PREV ;
} else if ( ! strcmp ( input , profile - > next_msg_key ) ) {
cbt - > move = VM_MOVE_NEXT ;
} else if ( ! strcmp ( input , profile - > listen_file_key ) ) {
2009-07-28 01:57:34 +00:00
* cc . buf = ' \0 ' ;
2007-12-26 17:37:13 +00:00
goto play_file ;
} else if ( ! strcmp ( input , profile - > callback_key ) ) {
switch_core_session_execute_exten ( session , cbt - > cid_number , profile - > callback_dialplan , profile - > callback_context ) ;
2008-09-08 21:56:07 +00:00
} else if ( ! strcmp ( input , profile - > forward_key ) ) {
char * cmd = NULL ;
char * new_file_path = NULL ;
char vm_cc [ 256 ] = " " ;
char macro_buf [ 80 ] = " " ;
2010-02-06 03:38:24 +00:00
2008-09-08 21:56:07 +00:00
switch_snprintf ( key_buf , sizeof ( key_buf ) , " %s:%s " , profile - > prepend_key , profile - > forward_key ) ;
TRY_CODE ( vm_macro_get ( session , VM_FORWARD_PREPEND_MACRO , key_buf , input , sizeof ( input ) , 1 , " " , & term , profile - > digit_timeout ) ) ;
if ( ! strcmp ( input , profile - > prepend_key ) ) {
switch_uuid_t uuid ;
char uuid_str [ SWITCH_UUID_FORMATTED_LENGTH + 1 ] ;
switch_size_t message_len = 0 ;
char * new_path = NULL ;
2010-02-06 03:38:24 +00:00
2008-09-08 21:56:07 +00:00
switch_uuid_get ( & uuid ) ;
switch_uuid_format ( uuid_str , & uuid ) ;
2010-02-06 03:38:24 +00:00
forward_file_path =
switch_core_session_sprintf ( session , " %s%smsg_%s.wav " , SWITCH_GLOBAL_dirs . temp_dir , SWITCH_PATH_SEPARATOR , uuid_str ) ;
2008-11-26 21:04:21 +00:00
TRY_CODE ( create_file ( session , profile , VM_RECORD_MESSAGE_MACRO , forward_file_path , & message_len , SWITCH_TRUE , NULL , NULL ) ) ;
2008-09-08 21:56:07 +00:00
if ( ( new_path = vm_merge_file ( session , profile , forward_file_path , cbt - > file_path ) ) ) {
2008-12-10 00:48:24 +00:00
switch_ivr_sleep ( session , 1500 , SWITCH_TRUE , NULL ) ;
2008-09-08 21:56:07 +00:00
forward_file_path = new_path ;
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Error merging files \n " ) ;
2008-09-08 21:56:07 +00:00
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_ACK_MACRO , " deleted " , NULL , NULL ) ) ;
goto end ;
}
new_file_path = forward_file_path ;
} else {
new_file_path = cbt - > file_path ;
}
2010-02-06 03:38:24 +00:00
get_exten :
2008-09-08 21:56:07 +00:00
switch_snprintf ( macro_buf , sizeof ( macro_buf ) , " phrase:%s:%s " , VM_FORWARD_MESSAGE_ENTER_EXTENSION_MACRO , profile - > terminator_key ) ;
vm_cc [ 0 ] = ' \0 ' ;
2010-02-06 03:38:24 +00:00
TRY_CODE ( switch_ivr_read
( session , 0 , sizeof ( vm_cc ) , macro_buf , NULL , vm_cc , sizeof ( vm_cc ) , profile - > digit_timeout , profile - > terminator_key ) ) ;
2010-01-13 20:29:21 +00:00
cmd = switch_core_session_sprintf ( session , " %s@%s %s %s '%s' " , vm_cc , cbt - > domain , new_file_path , cbt - > cid_number , cbt - > cid_name ) ;
2008-09-08 21:56:07 +00:00
if ( voicemail_inject ( cmd ) = = SWITCH_STATUS_SUCCESS ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Sent Carbon Copy to %s \n " , vm_cc ) ;
2008-09-08 21:56:07 +00:00
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_ACK_MACRO , " saved " , NULL , NULL ) ) ;
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Failed to Carbon Copy to %s \n " , vm_cc ) ;
2008-09-08 21:56:07 +00:00
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_INVALID_EXTENSION_MACRO , vm_cc , NULL , NULL ) ) ;
goto get_exten ;
}
2007-12-26 17:37:13 +00:00
} else if ( ! strcmp ( input , profile - > delete_file_key ) | | ! strcmp ( input , profile - > email_key ) ) {
2008-03-18 22:13:32 +00:00
char * sql = switch_mprintf ( " update voicemail_msgs set flags='delete' where uuid='%s' " , cbt - > uuid ) ;
2007-12-26 17:37:13 +00:00
vm_execute_sql ( profile , sql , profile - > mutex ) ;
switch_safe_free ( sql ) ;
2009-10-23 16:03:42 +00:00
if ( ! strcmp ( input , profile - > email_key ) & & ! zstr ( cbt - > email ) ) {
2007-12-26 17:37:13 +00:00
switch_event_t * event ;
char * from ;
char * headers , * header_string ;
char * body ;
int priority = 3 ;
switch_size_t retsize ;
switch_time_exp_t tm ;
char date [ 80 ] = " " ;
2008-05-27 04:54:52 +00:00
char tmp [ 50 ] = " " ;
2007-12-26 17:37:13 +00:00
int total_new_messages = 0 ;
int total_saved_messages = 0 ;
int total_new_urgent_messages = 0 ;
int total_saved_urgent_messages = 0 ;
int32_t message_len = 0 ;
char * p ;
2008-08-28 05:17:02 +00:00
switch_time_t l_duration = 0 ;
2007-12-26 17:37:13 +00:00
switch_core_time_duration_t duration ;
char duration_str [ 80 ] ;
if ( ! strcasecmp ( cbt - > read_flags , URGENT_FLAG_STRING ) ) {
priority = 1 ;
}
2007-10-23 14:45:22 +00:00
2007-12-15 04:58:44 +00:00
message_count ( profile , cbt - > user , cbt - > domain , cbt - > in_folder , & total_new_messages , & total_saved_messages ,
2008-05-27 04:54:52 +00:00
& total_new_urgent_messages , & total_saved_urgent_messages ) ;
2007-12-26 17:37:13 +00:00
2010-02-06 03:38:24 +00:00
switch_time_exp_lt ( & tm , switch_time_make ( atol ( cbt - > created_epoch ) , 0 ) ) ;
2007-12-26 17:37:13 +00:00
switch_strftime ( date , & retsize , sizeof ( date ) , profile - > date_fmt , & tm ) ;
2008-05-27 04:54:52 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , total_new_messages ) ;
2007-12-26 17:37:13 +00:00
switch_channel_set_variable ( channel , " voicemail_total_new_messages " , tmp ) ;
2008-05-27 04:54:52 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , total_saved_messages ) ;
2007-12-26 17:37:13 +00:00
switch_channel_set_variable ( channel , " voicemail_total_saved_messages " , tmp ) ;
2008-05-27 04:54:52 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , total_new_urgent_messages ) ;
2007-12-26 17:37:13 +00:00
switch_channel_set_variable ( channel , " voicemail_urgent_new_messages " , tmp ) ;
2008-05-27 04:54:52 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , total_saved_urgent_messages ) ;
2007-12-26 17:37:13 +00:00
switch_channel_set_variable ( channel , " voicemail_urgent_saved_messages " , tmp ) ;
switch_channel_set_variable ( channel , " voicemail_current_folder " , cbt - > in_folder ) ;
switch_channel_set_variable ( channel , " voicemail_account " , cbt - > user ) ;
switch_channel_set_variable ( channel , " voicemail_domain " , cbt - > domain ) ;
switch_channel_set_variable ( channel , " voicemail_caller_id_number " , cbt - > cid_number ) ;
switch_channel_set_variable ( channel , " voicemail_caller_id_name " , cbt - > cid_name ) ;
switch_channel_set_variable ( channel , " voicemail_file_path " , cbt - > file_path ) ;
switch_channel_set_variable ( channel , " voicemail_read_flags " , cbt - > read_flags ) ;
switch_channel_set_variable ( channel , " voicemail_time " , date ) ;
2008-05-27 04:54:52 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , priority ) ;
2007-12-26 17:37:13 +00:00
switch_channel_set_variable ( channel , " voicemail_priority " , tmp ) ;
message_len = atoi ( cbt - > message_len ) ;
2010-02-06 03:38:24 +00:00
l_duration = switch_time_make ( atol ( cbt - > message_len ) , 0 ) ;
2007-12-26 17:37:13 +00:00
switch_core_measure_time ( l_duration , & duration ) ;
duration . day + = duration . yr * 365 ;
duration . hr + = duration . day * 24 ;
2008-05-27 04:54:52 +00:00
switch_snprintf ( duration_str , sizeof ( duration_str ) , " %.2u:%.2u:%.2u " , duration . hr , duration . min , duration . sec ) ;
2007-12-26 17:37:13 +00:00
switch_channel_set_variable ( channel , " voicemail_message_len " , duration_str ) ;
switch_channel_set_variable ( channel , " voicemail_email " , cbt - > email ) ;
2009-10-23 16:03:42 +00:00
if ( zstr ( profile - > email_headers ) ) {
2007-12-26 17:37:13 +00:00
from = switch_core_session_sprintf ( session , " %s@%s " , cbt - > user , cbt - > domain ) ;
} else {
2008-05-27 04:54:52 +00:00
from = switch_channel_expand_variables ( channel , profile - > email_from ) ;
2007-12-26 17:37:13 +00:00
}
2009-10-23 16:03:42 +00:00
if ( zstr ( profile - > email_headers ) ) {
2008-05-27 04:54:52 +00:00
headers = switch_core_session_sprintf ( session ,
" From: FreeSWITCH mod_voicemail <%s@%s> \n Subject: Voicemail from %s %s \n X-Priority: %d " ,
cbt - > user , cbt - > domain , cbt - > cid_name , cbt - > cid_number , priority ) ;
2007-12-26 17:37:13 +00:00
} else {
2008-05-27 04:54:52 +00:00
headers = switch_channel_expand_variables ( channel , profile - > email_headers ) ;
2007-12-26 17:37:13 +00:00
}
p = headers + ( strlen ( headers ) - 1 ) ;
if ( * p = = ' \n ' ) {
2008-05-27 04:54:52 +00:00
if ( * ( p - 1 ) = = ' \r ' ) {
2007-12-26 17:37:13 +00:00
p - - ;
}
* p = ' \0 ' ;
}
header_string = switch_core_session_sprintf ( session , " %s \n X-Voicemail-Length: %u " , headers , message_len ) ;
2008-10-02 17:10:05 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_GENERAL ) = = SWITCH_STATUS_SUCCESS ) {
2008-10-06 23:05:55 +00:00
/* this isn't done? it was in the other place
2008-05-27 04:54:52 +00:00
* switch_channel_event_set_data ( channel , event ) ;
*/
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Message-Type " , " forwarded-voicemail " ) ;
2007-12-26 17:37:13 +00:00
switch_event_fire ( & event ) ;
}
if ( profile - > email_body ) {
body = switch_channel_expand_variables ( channel , profile - > email_body ) ;
} else {
2008-05-27 04:54:52 +00:00
body = switch_mprintf ( " %u second Voicemail from %s %s " , message_len , cbt - > cid_name , cbt - > cid_number ) ;
2007-12-26 17:37:13 +00:00
}
2009-10-01 22:43:44 +00:00
switch_simple_email ( cbt - > email , from , header_string , body , cbt - > file_path , cbt - > convert_cmd , cbt - > convert_ext ) ;
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Sending message to %s \n " , cbt - > email ) ;
2007-12-26 17:37:13 +00:00
switch_safe_free ( body ) ;
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_ACK_MACRO , " emailed " , NULL , NULL ) ) ;
} else {
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_ACK_MACRO , " deleted " , NULL , NULL ) ) ;
}
} else {
2008-03-18 22:13:32 +00:00
char * sql = switch_mprintf ( " update voicemail_msgs set flags='save' where uuid='%s' " , cbt - > uuid ) ;
2007-12-26 17:37:13 +00:00
vm_execute_sql ( profile , sql , profile - > mutex ) ;
switch_safe_free ( sql ) ;
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_ACK_MACRO , " saved " , NULL , NULL ) ) ;
}
}
}
2008-05-27 04:54:52 +00:00
end :
2007-12-26 17:37:13 +00:00
2008-09-08 21:56:07 +00:00
if ( forward_file_path ) {
2008-09-12 15:29:53 +00:00
if ( unlink ( forward_file_path ) ! = 0 ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Failed to delete file [%s] \n " , forward_file_path ) ;
2008-09-12 15:29:53 +00:00
}
2008-09-08 21:56:07 +00:00
}
2007-12-26 17:37:13 +00:00
return status ;
2007-10-12 03:28:59 +00:00
}
2008-08-28 05:28:05 +00:00
2008-10-08 21:47:41 +00:00
static void update_mwi ( vm_profile_t * profile , const char * id , const char * domain_name , const char * myfolder )
2008-08-28 05:28:05 +00:00
{
const char * yn = " no " ;
int total_new_messages = 0 ;
int total_saved_messages = 0 ;
int total_new_urgent_messages = 0 ;
int total_saved_urgent_messages = 0 ;
switch_event_t * event ;
2010-02-06 03:38:24 +00:00
message_count ( profile , id , domain_name , myfolder , & total_new_messages , & total_saved_messages , & total_new_urgent_messages ,
& total_saved_urgent_messages ) ;
2008-08-28 05:28:05 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_MESSAGE_WAITING ) ! = SWITCH_STATUS_SUCCESS ) {
return ;
}
if ( total_new_messages | | total_new_urgent_messages ) {
yn = " yes " ;
}
2009-04-21 01:02:45 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " MWI-Messages-Waiting " , yn ) ;
2008-10-20 12:54:37 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " MWI-Message-Account " , " %s@%s " , id , domain_name ) ;
2010-02-06 03:38:24 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " MWI-Voice-Message " , " %d/%d (%d/%d) " , total_new_messages , total_saved_messages ,
total_new_urgent_messages , total_saved_urgent_messages ) ;
2008-08-28 05:28:05 +00:00
switch_event_fire ( & event ) ;
}
2008-09-15 18:39:16 +00:00
# define FREE_DOMAIN_ROOT() if (x_domain_root) switch_xml_free(x_domain_root); x_user = x_domain = x_domain_root = NULL
2009-04-25 14:16:32 +00:00
static void voicemail_check_main ( switch_core_session_t * session , vm_profile_t * profile , const char * domain_name , const char * id , int auth )
2007-10-12 03:28:59 +00:00
{
2007-12-26 17:37:13 +00:00
vm_check_state_t vm_check_state = VM_CHECK_START ;
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2008-06-27 15:01:14 +00:00
switch_caller_profile_t * caller_profile = switch_channel_get_caller_profile ( channel ) ;
2008-01-28 07:26:10 +00:00
switch_xml_t x_domain = NULL , x_domain_root = NULL , x_user = NULL , x_params , x_param ;
2007-12-26 17:37:13 +00:00
switch_status_t status ;
char pass_buf [ 80 ] = " " , * mypass = NULL , id_buf [ 80 ] = " " , * myfolder = NULL ;
2009-05-18 17:06:13 +00:00
const char * thepass = NULL , * myid = id , * thehash = NULL , * vmhash = NULL ;
2007-12-26 17:37:13 +00:00
char term = 0 ;
2009-11-14 20:31:53 +00:00
uint32_t timeout , attempts = 0 , retries = 0 ;
2007-12-26 17:37:13 +00:00
int failed = 0 ;
msg_type_t play_msg_type = MSG_NONE ;
char * dir_path = NULL , * file_path = NULL ;
int total_new_messages = 0 ;
int total_saved_messages = 0 ;
int total_new_urgent_messages = 0 ;
int total_saved_urgent_messages = 0 ;
int heard_auto_saved = 0 , heard_auto_new = 0 ;
2009-11-25 00:23:07 +00:00
char * vm_email = NULL , * email_addr = NULL ;
2009-10-01 22:43:44 +00:00
char * convert_cmd = profile - > convert_cmd ;
char * convert_ext = profile - > convert_ext ;
2008-08-28 05:02:18 +00:00
char * vm_storage_dir = NULL ;
2008-08-20 22:06:04 +00:00
char global_buf [ 2 ] = " " ;
2008-04-18 22:05:44 +00:00
switch_input_args_t args = { 0 } ;
2008-06-27 15:01:14 +00:00
const char * caller_id_name = NULL ;
const char * caller_id_number = NULL ;
2009-04-25 14:16:32 +00:00
2008-06-27 15:01:14 +00:00
if ( ! ( caller_id_name = switch_channel_get_variable ( channel , " effective_caller_id_name " ) ) ) {
caller_id_name = caller_profile - > caller_id_name ;
}
if ( ! ( caller_id_number = switch_channel_get_variable ( channel , " effective_caller_id_number " ) ) ) {
caller_id_number = caller_profile - > caller_id_number ;
}
2007-12-26 17:37:13 +00:00
timeout = profile - > digit_timeout ;
attempts = profile - > max_login_attempts ;
2008-04-18 22:05:44 +00:00
status = switch_ivr_phrase_macro ( session , VM_HELLO_MACRO , NULL , NULL , & args ) ;
2008-08-20 22:06:04 +00:00
* global_buf = ' \0 ' ;
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
while ( switch_channel_ready ( channel ) ) {
2008-12-10 00:48:24 +00:00
switch_ivr_sleep ( session , 100 , SWITCH_TRUE , NULL ) ;
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
switch ( vm_check_state ) {
case VM_CHECK_START :
{
total_new_messages = 0 ;
total_saved_messages = 0 ;
total_new_urgent_messages = 0 ;
total_saved_urgent_messages = 0 ;
heard_auto_saved = 0 ;
heard_auto_new = 0 ;
play_msg_type = MSG_NONE ;
attempts = profile - > max_login_attempts ;
2009-11-14 20:31:53 +00:00
retries = profile - > max_retries ;
2008-05-27 04:54:52 +00:00
myid = id ;
mypass = NULL ;
myfolder = " inbox " ;
vm_check_state = VM_CHECK_AUTH ;
2008-09-15 18:39:16 +00:00
FREE_DOMAIN_ROOT ( ) ;
2008-05-27 04:54:52 +00:00
}
break ;
case VM_CHECK_FOLDER_SUMMARY :
{
int informed = 0 ;
char msg_count [ 80 ] = " " ;
2008-09-02 09:56:09 +00:00
switch_input_args_t folder_args = { 0 } ;
2008-10-29 17:28:12 +00:00
switch_event_t * params ;
2010-02-06 03:38:24 +00:00
2008-09-02 09:56:09 +00:00
folder_args . input_callback = cancel_on_dtmf ;
folder_args . buf = & global_buf ;
folder_args . buflen = sizeof ( global_buf ) ;
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
switch_channel_set_variable ( channel , " voicemail_current_folder " , myfolder ) ;
message_count ( profile , myid , domain_name , myfolder , & total_new_messages , & total_saved_messages ,
& total_new_urgent_messages , & total_saved_urgent_messages ) ;
2007-12-26 17:37:13 +00:00
2008-10-29 17:28:12 +00:00
switch_event_create_subclass ( & params , SWITCH_EVENT_CUSTOM , VM_EVENT_MAINT ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " VM-Action " , " folder-summary " ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " VM-User " , myid ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " VM-Domain " , domain_name ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " VM-Folder " , myfolder ) ;
switch_event_add_header ( params , SWITCH_STACK_BOTTOM , " VM-Total-New-Messages " , " %u " , total_new_messages ) ;
switch_event_add_header ( params , SWITCH_STACK_BOTTOM , " VM-Total-Saved-Messages " , " %u " , total_saved_messages ) ;
switch_event_add_header ( params , SWITCH_STACK_BOTTOM , " VM-Total-New-Urgent-Messages " , " %u " , total_new_urgent_messages ) ;
switch_event_add_header ( params , SWITCH_STACK_BOTTOM , " VM-Total-Saved-Urgent-Messages " , " %u " , total_saved_urgent_messages ) ;
switch_event_fire ( & params ) ;
2008-05-27 04:54:52 +00:00
if ( total_new_urgent_messages > 0 ) {
switch_snprintf ( msg_count , sizeof ( msg_count ) , " %d:urgent-new " , total_new_urgent_messages ) ;
2008-09-02 09:56:09 +00:00
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_MESSAGE_COUNT_MACRO , msg_count , NULL , & folder_args ) ) ;
2008-05-27 04:54:52 +00:00
informed + + ;
2009-10-23 16:03:42 +00:00
if ( ! zstr_buf ( global_buf ) ) {
2008-08-20 22:06:04 +00:00
vm_check_state = VM_CHECK_MENU ;
continue ;
}
2008-05-27 04:54:52 +00:00
}
if ( total_new_messages > 0 & & total_new_messages ! = total_new_urgent_messages ) {
switch_snprintf ( msg_count , sizeof ( msg_count ) , " %d:new " , total_new_messages ) ;
2008-09-02 09:56:09 +00:00
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_MESSAGE_COUNT_MACRO , msg_count , NULL , & folder_args ) ) ;
2008-05-27 04:54:52 +00:00
informed + + ;
2009-10-23 16:03:42 +00:00
if ( ! zstr_buf ( global_buf ) ) {
2008-08-20 22:06:04 +00:00
vm_check_state = VM_CHECK_MENU ;
continue ;
}
2008-05-27 04:54:52 +00:00
}
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
if ( ! heard_auto_new & & total_new_messages + total_new_urgent_messages > 0 ) {
heard_auto_new = 1 ;
play_msg_type = MSG_NEW ;
vm_check_state = VM_CHECK_PLAY_MESSAGES ;
continue ;
}
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
if ( ! informed ) {
switch_snprintf ( msg_count , sizeof ( msg_count ) , " 0:new " ) ;
2008-09-02 09:56:09 +00:00
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_MESSAGE_COUNT_MACRO , msg_count , NULL , & folder_args ) ) ;
2009-09-24 15:48:31 +00:00
switch_snprintf ( msg_count , sizeof ( msg_count ) , " %d:saved " , total_saved_messages + total_saved_urgent_messages ) ;
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_MESSAGE_COUNT_MACRO , msg_count , NULL , & folder_args ) ) ;
2008-05-27 04:54:52 +00:00
informed + + ;
}
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
vm_check_state = VM_CHECK_MENU ;
2007-12-26 17:37:13 +00:00
}
2008-05-27 04:54:52 +00:00
break ;
case VM_CHECK_PLAY_MESSAGES :
{
listen_callback_t cbt ;
char sql [ 256 ] ;
int cur_message , total_messages ;
message_count ( profile , myid , domain_name , myfolder , & total_new_messages , & total_saved_messages ,
& total_new_urgent_messages , & total_saved_urgent_messages ) ;
memset ( & cbt , 0 , sizeof ( cbt ) ) ;
2009-11-25 00:23:07 +00:00
cbt . email = vm_email ? vm_email : email_addr ;
2009-10-01 22:43:44 +00:00
cbt . convert_cmd = convert_cmd ;
cbt . convert_ext = convert_ext ;
2009-07-27 18:44:30 +00:00
cbt . move = VM_MOVE_NEXT ;
2008-05-27 04:54:52 +00:00
switch ( play_msg_type ) {
case MSG_NEW :
{
switch_snprintf ( sql , sizeof ( sql ) ,
2009-01-19 20:58:01 +00:00
" select * from voicemail_msgs where username='%s' and domain='%s' and read_epoch=0 "
" order by read_flags, created_epoch " , myid , domain_name ) ;
2008-05-27 04:54:52 +00:00
total_messages = total_new_messages ;
heard_auto_new = heard_auto_saved = 1 ;
}
break ;
case MSG_SAVED :
default :
{
switch_snprintf ( sql , sizeof ( sql ) ,
2009-01-19 20:58:01 +00:00
" select * from voicemail_msgs where username='%s' and domain='%s' and read_epoch !=0 "
" order by read_flags, created_epoch " , myid , domain_name ) ;
2008-05-27 04:54:52 +00:00
total_messages = total_saved_messages ;
heard_auto_new = heard_auto_saved = 1 ;
}
break ;
}
for ( cur_message = 0 ; cur_message < total_messages ; cur_message + + ) {
cbt . index = 0 ;
cbt . want = cur_message ;
cbt . type = play_msg_type ;
2009-07-27 18:44:30 +00:00
cbt . move = VM_MOVE_NEXT ;
2008-05-27 04:54:52 +00:00
vm_execute_sql_callback ( profile , profile - > mutex , sql , listen_callback , & cbt ) ;
status = listen_file ( session , profile , & cbt ) ;
2009-07-27 18:44:30 +00:00
if ( cbt . move = = VM_MOVE_PREV ) {
if ( cur_message < = 0 ) {
cur_message = - 1 ;
} else {
cur_message - = 2 ;
}
}
2008-05-27 04:54:52 +00:00
if ( status ! = SWITCH_STATUS_SUCCESS & & status ! = SWITCH_STATUS_BREAK ) {
break ;
}
}
2010-03-15 20:40:49 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " update voicemail_msgs set read_epoch=%ld where read_epoch=0 and "
" username='%s' and domain='%s' and flags='save' " ,
2009-01-25 21:23:07 +00:00
( long ) switch_epoch_time_now ( NULL ) , myid , domain_name ) ;
2008-05-27 04:54:52 +00:00
vm_execute_sql ( profile , sql , profile - > mutex ) ;
switch_snprintf ( sql , sizeof ( sql ) , " select file_path from voicemail_msgs where username='%s' and domain='%s' and flags='delete' " , myid ,
domain_name ) ;
vm_execute_sql_callback ( profile , profile - > mutex , sql , unlink_callback , NULL ) ;
switch_snprintf ( sql , sizeof ( sql ) , " delete from voicemail_msgs where username='%s' and domain='%s' and flags='delete' " , myid , domain_name ) ;
vm_execute_sql ( profile , sql , profile - > mutex ) ;
vm_check_state = VM_CHECK_FOLDER_SUMMARY ;
2007-12-26 17:37:13 +00:00
2009-05-18 17:06:13 +00:00
update_mwi ( profile , myid , domain_name , myfolder ) ;
2007-12-26 17:37:13 +00:00
}
2008-05-27 04:54:52 +00:00
break ;
case VM_CHECK_CONFIG :
{
char * sql = NULL ;
char input [ 10 ] = " " ;
char key_buf [ 80 ] = " " ;
callback_t cbt = { 0 } ;
char msg_count [ 80 ] = " " ;
cc_t cc = { 0 } ;
switch_size_t message_len = 0 ;
cbt . buf = msg_count ;
cbt . len = sizeof ( msg_count ) ;
sql = switch_mprintf ( " select count(*) from voicemail_prefs where username='%q' and domain = '%q' " , myid , domain_name ) ;
vm_execute_sql_callback ( profile , profile - > mutex , sql , sql2str_callback , & cbt ) ;
switch_safe_free ( sql ) ;
if ( * msg_count = = ' \0 ' | | ! atoi ( msg_count ) ) {
2008-08-20 22:06:04 +00:00
sql = switch_mprintf ( " insert into voicemail_prefs values('%q','%q','','','') " , myid , domain_name ) ;
2008-05-27 04:54:52 +00:00
vm_execute_sql ( profile , sql , profile - > mutex ) ;
switch_safe_free ( sql ) ;
}
2007-12-26 17:37:13 +00:00
2008-08-20 22:06:04 +00:00
switch_snprintf ( key_buf , sizeof ( key_buf ) , " %s:%s:%s:%s:%s " ,
2010-02-06 03:38:24 +00:00
profile - > record_greeting_key ,
profile - > choose_greeting_key , profile - > record_name_key , profile - > change_pass_key , profile - > main_menu_key ) ;
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
TRY_CODE ( vm_macro_get ( session , VM_CONFIG_MENU_MACRO , key_buf , input , sizeof ( input ) , 1 , " " , & term , timeout ) ) ;
if ( status ! = SWITCH_STATUS_SUCCESS & & status ! = SWITCH_STATUS_BREAK ) {
goto end ;
}
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
if ( ! strcmp ( input , profile - > main_menu_key ) ) {
vm_check_state = VM_CHECK_MENU ;
} else if ( ! strcmp ( input , profile - > choose_greeting_key ) ) {
int num ;
switch_input_args_t greeting_args = { 0 } ;
greeting_args . input_callback = cancel_on_dtmf ;
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
TRY_CODE ( vm_macro_get ( session , VM_CHOOSE_GREETING_MACRO , key_buf , input , sizeof ( input ) , 1 , " " , & term , timeout ) ) ;
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
num = atoi ( input ) ;
file_path = switch_mprintf ( " %s%sgreeting_%d.%s " , dir_path , SWITCH_PATH_SEPARATOR , num , profile - > file_ext ) ;
if ( num < 1 | | num > VM_MAX_GREETINGS ) {
status = SWITCH_STATUS_FALSE ;
} else {
switch_file_handle_t fh = { 0 } ;
memset ( & fh , 0 , sizeof ( fh ) ) ;
greeting_args . input_callback = control_playback ;
memset ( & cc , 0 , sizeof ( cc ) ) ;
cc . profile = profile ;
cc . fh = & fh ;
cc . noexit = 1 ;
greeting_args . buf = & cc ;
2009-07-01 17:04:15 +00:00
status = switch_ivr_play_file ( session , & fh , file_path , & greeting_args ) ;
2008-05-27 04:54:52 +00:00
}
if ( status ! = SWITCH_STATUS_SUCCESS & & status ! = SWITCH_STATUS_BREAK ) {
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_CHOOSE_GREETING_FAIL_MACRO , NULL , NULL , NULL ) ) ;
} else {
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_CHOOSE_GREETING_SELECTED_MACRO , input , NULL , NULL ) ) ;
sql =
switch_mprintf ( " update voicemail_prefs set greeting_path='%s' where username='%s' and domain='%s' " , file_path , myid ,
domain_name ) ;
vm_execute_sql ( profile , sql , profile - > mutex ) ;
switch_safe_free ( sql ) ;
}
switch_safe_free ( file_path ) ;
} else if ( ! strcmp ( input , profile - > record_greeting_key ) ) {
int num ;
TRY_CODE ( vm_macro_get ( session , VM_CHOOSE_GREETING_MACRO , key_buf , input , sizeof ( input ) , 1 , " " , & term , timeout ) ) ;
num = atoi ( input ) ;
if ( num < 1 | | num > VM_MAX_GREETINGS ) {
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_CHOOSE_GREETING_FAIL_MACRO , NULL , NULL , NULL ) ) ;
} else {
file_path = switch_mprintf ( " %s%sgreeting_%d.%s " , dir_path , SWITCH_PATH_SEPARATOR , num , profile - > file_ext ) ;
2008-11-26 21:04:21 +00:00
TRY_CODE ( create_file ( session , profile , VM_RECORD_GREETING_MACRO , file_path , & message_len , SWITCH_TRUE , NULL , NULL ) ) ;
2008-05-27 04:54:52 +00:00
sql =
switch_mprintf ( " update voicemail_prefs set greeting_path='%s' where username='%s' and domain='%s' " , file_path , myid ,
domain_name ) ;
vm_execute_sql ( profile , sql , profile - > mutex ) ;
switch_safe_free ( sql ) ;
switch_safe_free ( file_path ) ;
}
2008-08-20 22:06:04 +00:00
} else if ( ! strcmp ( input , profile - > change_pass_key ) ) {
char buf [ 256 ] = " " ;
char macro [ 256 ] = " " ;
2008-10-29 17:28:12 +00:00
switch_event_t * params ;
switch_xml_t xx_user , xx_domain , xx_domain_root ;
2008-08-20 22:06:04 +00:00
switch_snprintf ( macro , sizeof ( macro ) , " phrase:%s:%s " , VM_ENTER_PASS_MACRO , profile - > terminator_key ) ;
2008-09-08 22:34:28 +00:00
TRY_CODE ( switch_ivr_read ( session , 0 , 255 , macro , NULL , buf , sizeof ( buf ) , 10000 , profile - > terminator_key ) ) ;
2008-08-20 22:06:04 +00:00
sql = switch_mprintf ( " update voicemail_prefs set password='%s' where username='%s' and domain='%s' " , buf , myid , domain_name ) ;
vm_execute_sql ( profile , sql , profile - > mutex ) ;
switch_safe_free ( file_path ) ;
switch_safe_free ( sql ) ;
2008-10-29 17:28:12 +00:00
switch_event_create_subclass ( & params , SWITCH_EVENT_CUSTOM , VM_EVENT_MAINT ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " VM-Action " , " change-password " ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " VM-User-Password " , buf ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " VM-User " , myid ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " VM-Domain " , domain_name ) ;
switch_channel_event_set_data ( channel , params ) ;
2010-02-06 03:38:24 +00:00
2009-05-18 17:06:13 +00:00
if ( switch_xml_locate_user ( " id " , myid , domain_name , switch_channel_get_variable ( channel , " network_addr " ) ,
2008-12-23 17:36:50 +00:00
& xx_domain_root , & xx_domain , & xx_user , NULL , params ) = = SWITCH_STATUS_SUCCESS ) {
2008-10-29 17:28:12 +00:00
switch_xml_free ( xx_domain_root ) ;
}
switch_event_fire ( & params ) ;
2010-02-06 03:38:24 +00:00
2008-05-27 04:54:52 +00:00
} else if ( ! strcmp ( input , profile - > record_name_key ) ) {
file_path = switch_mprintf ( " %s%srecorded_name.%s " , dir_path , SWITCH_PATH_SEPARATOR , profile - > file_ext ) ;
2008-11-26 21:04:21 +00:00
TRY_CODE ( create_file ( session , profile , VM_RECORD_NAME_MACRO , file_path , & message_len , SWITCH_FALSE , NULL , NULL ) ) ;
2008-05-27 04:54:52 +00:00
sql = switch_mprintf ( " update voicemail_prefs set name_path='%s' where username='%s' and domain='%s' " , file_path , myid , domain_name ) ;
vm_execute_sql ( profile , sql , profile - > mutex ) ;
switch_safe_free ( file_path ) ;
switch_safe_free ( sql ) ;
}
continue ;
2007-12-26 17:37:13 +00:00
}
2008-05-27 04:54:52 +00:00
break ;
case VM_CHECK_MENU :
{
char input [ 10 ] = " " ;
char key_buf [ 80 ] = " " ;
play_msg_type = MSG_NONE ;
2009-11-14 20:31:53 +00:00
if ( ! retries ) {
goto end ;
}
retries - - ;
2009-10-23 16:03:42 +00:00
if ( ! zstr_buf ( global_buf ) ) {
2008-08-20 22:06:04 +00:00
switch_set_string ( input , global_buf ) ;
* global_buf = ' \0 ' ;
status = SWITCH_STATUS_SUCCESS ;
} else {
switch_snprintf ( key_buf , sizeof ( key_buf ) , " %s:%s:%s:%s " ,
profile - > play_new_messages_key , profile - > play_saved_messages_key , profile - > config_menu_key , profile - > terminator_key ) ;
2010-02-06 03:38:24 +00:00
2008-08-20 22:06:04 +00:00
status = vm_macro_get ( session , VM_MENU_MACRO , key_buf , input , sizeof ( input ) , 1 , " " , & term , timeout ) ;
}
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
if ( status ! = SWITCH_STATUS_SUCCESS & & status ! = SWITCH_STATUS_BREAK ) {
goto end ;
}
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
if ( ! strcmp ( input , profile - > play_new_messages_key ) ) {
play_msg_type = MSG_NEW ;
} else if ( ! strcmp ( input , profile - > play_saved_messages_key ) ) {
play_msg_type = MSG_SAVED ;
} else if ( ! strcmp ( input , profile - > terminator_key ) ) {
goto end ;
} else if ( ! strcmp ( input , profile - > config_menu_key ) ) {
vm_check_state = VM_CHECK_CONFIG ;
}
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
if ( play_msg_type ) {
vm_check_state = VM_CHECK_PLAY_MESSAGES ;
2009-11-14 20:31:53 +00:00
retries = profile - > max_retries ;
2008-05-27 04:54:52 +00:00
}
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
continue ;
}
break ;
case VM_CHECK_AUTH :
{
2010-02-06 03:38:24 +00:00
prefs_callback_t cbt = { { 0 }
} ;
2008-08-20 22:06:04 +00:00
char sql [ 512 ] = " " ;
2008-05-27 04:54:52 +00:00
if ( ! attempts ) {
failed = 1 ;
goto end ;
}
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
attempts - - ;
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
if ( ! myid ) {
status = vm_macro_get ( session , VM_ENTER_ID_MACRO , profile - > terminator_key , id_buf , sizeof ( id_buf ) , 0 ,
profile - > terminator_key , & term , timeout ) ;
if ( status ! = SWITCH_STATUS_SUCCESS ) {
goto end ;
}
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
if ( * id_buf = = ' \0 ' ) {
continue ;
} else {
myid = id_buf ;
}
}
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
if ( ! x_user ) {
switch_event_t * params ;
int ok = 1 ;
2008-06-27 15:01:14 +00:00
2007-12-26 17:37:13 +00:00
2008-10-02 17:10:05 +00:00
switch_event_create ( & params , SWITCH_EVENT_GENERAL ) ;
2008-05-27 04:54:52 +00:00
switch_assert ( params ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " destination_number " , caller_profile - > destination_number ) ;
2008-06-27 15:01:14 +00:00
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " caller_id_number " , caller_id_number ) ;
2010-02-06 03:38:24 +00:00
2008-05-27 04:54:52 +00:00
if ( switch_xml_locate_user ( " id " , myid , domain_name , switch_channel_get_variable ( channel , " network_addr " ) ,
2008-12-23 17:36:50 +00:00
& x_domain_root , & x_domain , & x_user , NULL , params ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Can't find user [%s@%s] \n " , myid , domain_name ) ;
2008-05-27 04:54:52 +00:00
ok = 0 ;
2009-05-18 17:06:13 +00:00
} else {
2009-05-18 17:34:35 +00:00
myid = switch_core_session_strdup ( session , switch_xml_attr ( x_user , " id " ) ) ;
2008-05-27 04:54:52 +00:00
}
2009-05-18 17:06:13 +00:00
2008-05-27 04:54:52 +00:00
switch_event_destroy ( & params ) ;
if ( ! ok ) {
goto end ;
}
2007-12-26 17:37:13 +00:00
}
2008-10-20 22:52:09 +00:00
thepass = thehash = NULL ;
2008-08-20 22:06:04 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " select * from voicemail_prefs where username='%s' and domain='%s' " , myid , domain_name ) ;
vm_execute_sql_callback ( profile , profile - > mutex , sql , prefs_callback , & cbt ) ;
2008-10-31 20:24:06 +00:00
x_params = switch_xml_child ( x_user , " variables " ) ;
for ( x_param = switch_xml_child ( x_params , " variable " ) ; x_param ; x_param = x_param - > next ) {
const char * var = switch_xml_attr_soft ( x_param , " name " ) ;
const char * val = switch_xml_attr_soft ( x_param , " value " ) ;
if ( ! strcasecmp ( var , " timezone " ) ) {
switch_channel_set_variable ( channel , var , val ) ;
}
}
x_params = switch_xml_child ( x_user , " params " ) ;
2008-05-27 04:54:52 +00:00
for ( x_param = switch_xml_child ( x_params , " param " ) ; x_param ; x_param = x_param - > next ) {
const char * var = switch_xml_attr_soft ( x_param , " name " ) ;
const char * val = switch_xml_attr_soft ( x_param , " value " ) ;
2010-02-06 03:38:24 +00:00
2008-10-20 22:52:09 +00:00
if ( ! strcasecmp ( var , " a1-hash " ) ) {
2009-03-17 16:28:16 +00:00
thehash = switch_core_session_strdup ( session , val ) ;
2008-10-20 23:42:00 +00:00
} else if ( ! strcasecmp ( var , " vm-a1-hash " ) ) {
2009-03-17 16:28:16 +00:00
vmhash = switch_core_session_strdup ( session , val ) ;
2008-10-24 00:28:10 +00:00
} else if ( ! auth & & ! thepass & & ! strcasecmp ( var , " password " ) ) {
2009-03-17 16:28:16 +00:00
thepass = switch_core_session_strdup ( session , val ) ;
2008-10-24 00:28:10 +00:00
} else if ( ! auth & & ! strcasecmp ( var , " vm-password " ) ) {
2009-10-23 16:03:42 +00:00
if ( ! zstr ( val ) & & ! strcasecmp ( val , " user-choose " ) ) {
if ( zstr ( cbt . password ) ) {
2008-10-24 00:28:10 +00:00
auth = 1 ;
} else {
2009-03-17 16:28:16 +00:00
thepass = switch_core_session_strdup ( session , val ) ;
2008-10-24 00:28:10 +00:00
}
} else {
2009-03-17 16:28:16 +00:00
thepass = switch_core_session_strdup ( session , val ) ;
2008-10-24 00:28:10 +00:00
}
2008-05-27 04:54:52 +00:00
} else if ( ! strcasecmp ( var , " vm-mailto " ) ) {
2008-06-04 22:52:37 +00:00
vm_email = switch_core_session_strdup ( session , val ) ;
2009-11-25 00:23:07 +00:00
email_addr = switch_core_session_strdup ( session , val ) ;
} else if ( ! strcasecmp ( var , " email-addr " ) ) {
email_addr = switch_core_session_strdup ( session , val ) ;
2009-10-01 22:43:44 +00:00
} else if ( ! strcasecmp ( var , " vm-convert-cmd " ) ) {
convert_cmd = switch_core_session_strdup ( session , val ) ;
} else if ( ! strcasecmp ( var , " vm-convert-ext " ) ) {
convert_ext = switch_core_session_strdup ( session , val ) ;
2008-08-28 05:02:18 +00:00
} else if ( ! strcasecmp ( var , " storage-dir " ) ) {
vm_storage_dir = switch_core_session_strdup ( session , val ) ;
2010-02-06 03:38:24 +00:00
2008-10-31 20:24:06 +00:00
} else if ( ! strcasecmp ( var , " timezone " ) ) {
switch_channel_set_variable ( channel , var , val ) ;
2010-02-06 03:38:24 +00:00
}
2008-10-24 00:28:10 +00:00
2007-12-26 17:37:13 +00:00
}
2008-10-29 17:28:12 +00:00
if ( ! mypass ) {
if ( auth ) {
mypass = " OK " ;
} else {
status = vm_macro_get ( session , VM_ENTER_PASS_MACRO , profile - > terminator_key ,
pass_buf , sizeof ( pass_buf ) , 0 , profile - > terminator_key , & term , timeout ) ;
if ( status ! = SWITCH_STATUS_SUCCESS ) {
goto end ;
}
if ( * pass_buf = = ' \0 ' ) {
continue ;
} else {
mypass = pass_buf ;
}
}
}
2008-10-20 23:42:00 +00:00
if ( vmhash ) {
thehash = vmhash ;
}
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( ! auth & & ! thepass & & ! zstr ( cbt . password ) ) {
2008-10-24 00:28:10 +00:00
thepass = cbt . password ;
}
2008-05-27 04:54:52 +00:00
2008-09-10 21:18:51 +00:00
if ( ! auth ) {
2009-10-23 16:03:42 +00:00
if ( ! zstr ( cbt . password ) & & ! strcmp ( cbt . password , mypass ) ) {
2008-09-10 21:18:51 +00:00
auth + + ;
} else if ( ! thepass ) {
auth + + ;
}
2008-10-20 22:52:09 +00:00
if ( ! auth & & ( thepass | | thehash ) & & mypass ) {
if ( thehash ) {
2008-10-20 23:27:29 +00:00
char digest [ SWITCH_MD5_DIGEST_STRING_SIZE ] = { 0 } ;
2008-10-20 22:52:09 +00:00
char * lpbuf = switch_mprintf ( " %s:%s:%s " , myid , domain_name , mypass ) ;
2008-10-20 23:27:29 +00:00
switch_md5_string ( digest , ( void * ) lpbuf , strlen ( lpbuf ) ) ;
2008-10-20 22:52:09 +00:00
if ( ! strcmp ( digest , thehash ) ) {
auth + + ;
}
switch_safe_free ( lpbuf ) ;
}
2010-02-06 03:38:24 +00:00
2008-10-20 22:52:09 +00:00
if ( ! auth & & thepass & & ! strcmp ( thepass , mypass ) ) {
auth + + ;
}
2008-09-10 21:18:51 +00:00
}
}
2008-09-15 18:39:16 +00:00
FREE_DOMAIN_ROOT ( ) ;
2010-02-06 03:38:24 +00:00
2008-09-10 21:18:51 +00:00
if ( auth ) {
2008-05-27 04:54:52 +00:00
if ( ! dir_path ) {
2009-10-23 16:03:42 +00:00
if ( ! zstr ( vm_storage_dir ) ) {
2008-08-28 05:02:18 +00:00
dir_path = switch_core_session_sprintf ( session , " %s%s%s " , vm_storage_dir , SWITCH_PATH_SEPARATOR , myid ) ;
2010-02-06 03:38:24 +00:00
} else if ( ! zstr ( profile - > storage_dir ) ) {
dir_path =
switch_core_session_sprintf ( session , " %s%s%s%s%s " , profile - > storage_dir , SWITCH_PATH_SEPARATOR , domain_name ,
SWITCH_PATH_SEPARATOR , myid ) ;
2008-08-28 05:02:18 +00:00
} else {
2008-05-27 04:54:52 +00:00
dir_path = switch_core_session_sprintf ( session , " %s%svoicemail%s%s%s%s%s%s " , SWITCH_GLOBAL_dirs . storage_dir ,
SWITCH_PATH_SEPARATOR ,
SWITCH_PATH_SEPARATOR ,
profile - > name , SWITCH_PATH_SEPARATOR , domain_name , SWITCH_PATH_SEPARATOR , myid ) ;
}
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
if ( switch_dir_make_recursive ( dir_path , SWITCH_DEFAULT_DIR_PERMS , switch_core_session_get_pool ( session ) ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Error creating %s \n " , dir_path ) ;
2008-09-15 18:39:16 +00:00
goto end ;
2008-05-27 04:54:52 +00:00
}
}
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
vm_check_state = VM_CHECK_FOLDER_SUMMARY ;
} else {
goto failed ;
}
2010-02-06 03:38:24 +00:00
2008-05-27 04:54:52 +00:00
continue ;
failed :
2010-02-06 03:38:24 +00:00
2008-09-15 18:39:16 +00:00
FREE_DOMAIN_ROOT ( ) ;
2008-05-27 04:54:52 +00:00
status = switch_ivr_phrase_macro ( session , VM_FAIL_AUTH_MACRO , NULL , NULL , NULL ) ;
myid = id ;
mypass = NULL ;
continue ;
}
break ;
default :
break ;
2007-12-26 17:37:13 +00:00
}
}
2008-05-27 04:54:52 +00:00
end :
2007-12-26 17:37:13 +00:00
if ( switch_channel_ready ( channel ) ) {
if ( failed ) {
status = switch_ivr_phrase_macro ( session , VM_ABORT_MACRO , NULL , NULL , NULL ) ;
}
status = switch_ivr_phrase_macro ( session , VM_GOODBYE_MACRO , NULL , NULL , NULL ) ;
}
if ( x_domain_root ) {
switch_xml_free ( x_domain_root ) ;
2008-09-15 18:39:16 +00:00
x_domain_root = NULL ;
2007-12-26 17:37:13 +00:00
}
2007-10-12 03:28:59 +00:00
}
2007-12-26 17:37:13 +00:00
2008-07-17 19:46:25 +00:00
2010-02-06 03:38:24 +00:00
static switch_status_t deliver_vm ( vm_profile_t * profile ,
switch_xml_t x_user ,
const char * domain_name ,
const char * path ,
2010-01-13 01:32:01 +00:00
uint32_t message_len ,
const char * read_flags ,
2010-02-06 03:38:24 +00:00
switch_event_t * params ,
switch_memory_pool_t * pool ,
const char * caller_id_name , const char * caller_id_number , const char * forwarded_by , switch_bool_t copy )
2008-07-17 19:46:25 +00:00
{
char * file_path = NULL , * dir_path = NULL ;
const char * myid = switch_xml_attr ( x_user , " id " ) ;
switch_uuid_t uuid ;
char uuid_str [ SWITCH_UUID_FORMATTED_LENGTH + 1 ] ;
const char * filename ;
switch_xml_t x_param , x_params ;
char * vm_email = NULL ;
char * vm_notify_email = NULL ;
char * email_addr = NULL ;
2008-09-26 19:48:55 +00:00
char * vm_timezone = NULL ;
2008-07-17 19:46:25 +00:00
int send_mail = 0 ;
int send_main = 0 ;
int send_notify = 0 ;
int insert_db = 1 ;
int email_attach = 0 ;
2008-08-28 05:02:18 +00:00
char * vm_storage_dir = NULL ;
2008-07-17 19:46:25 +00:00
char * myfolder = " inbox " ;
int priority = 3 ;
const char * tmp ;
switch_event_t * local_event = NULL ;
2008-09-08 21:56:07 +00:00
switch_status_t ret = SWITCH_STATUS_SUCCESS ;
2009-10-01 22:43:44 +00:00
char * convert_cmd = profile - > convert_cmd ;
char * convert_ext = profile - > convert_ext ;
2009-09-01 17:40:51 +00:00
if ( ! params ) {
2008-10-02 17:10:05 +00:00
switch_event_create ( & local_event , SWITCH_EVENT_REQUEST_PARAMS ) ;
2008-07-17 19:46:25 +00:00
params = local_event ;
}
2010-02-06 03:38:24 +00:00
2008-07-17 19:46:25 +00:00
if ( ( tmp = switch_event_get_header ( params , " effective_caller_id_name " ) ) ) {
caller_id_name = tmp ;
}
if ( ( tmp = switch_event_get_header ( params , " effective_caller_id_number " ) ) ) {
caller_id_number = tmp ;
}
2010-02-06 03:38:24 +00:00
2008-07-17 19:46:25 +00:00
switch_uuid_get ( & uuid ) ;
switch_uuid_format ( uuid_str , & uuid ) ;
if ( ( filename = strrchr ( path , * SWITCH_PATH_SEPARATOR ) ) ) {
filename + + ;
} else {
filename = path ;
}
2008-10-31 20:24:06 +00:00
x_params = switch_xml_child ( x_user , " variables " ) ;
for ( x_param = switch_xml_child ( x_params , " variable " ) ; x_param ; x_param = x_param - > next ) {
const char * var = switch_xml_attr_soft ( x_param , " name " ) ;
const char * val = switch_xml_attr_soft ( x_param , " value " ) ;
2010-02-06 03:38:24 +00:00
2008-10-31 20:24:06 +00:00
if ( ! strcasecmp ( var , " timezone " ) ) {
vm_timezone = switch_core_strdup ( pool , val ) ;
}
}
2008-09-08 21:56:07 +00:00
x_params = switch_xml_child ( x_user , " params " ) ;
2008-07-17 19:46:25 +00:00
for ( x_param = switch_xml_child ( x_params , " param " ) ; x_param ; x_param = x_param - > next ) {
const char * var = switch_xml_attr_soft ( x_param , " name " ) ;
const char * val = switch_xml_attr_soft ( x_param , " value " ) ;
if ( ! strcasecmp ( var , " vm-mailto " ) ) {
vm_email = switch_core_strdup ( pool , val ) ;
} else if ( ! strcasecmp ( var , " vm-notify-mailto " ) ) {
vm_notify_email = switch_core_strdup ( pool , val ) ;
} else if ( ! strcasecmp ( var , " email-addr " ) ) {
email_addr = switch_core_strdup ( pool , val ) ;
2008-12-03 15:45:20 +00:00
} else if ( ! strcasecmp ( var , " vm-email-all-messages " ) & & ( send_main = switch_true ( val ) ) ) {
2008-08-26 15:40:30 +00:00
send_mail + + ;
2008-12-03 15:45:20 +00:00
} else if ( ! strcasecmp ( var , " vm-notify-email-all-messages " ) & & ( send_notify = switch_true ( val ) ) ) {
2008-08-26 15:40:30 +00:00
send_mail + + ;
2008-07-17 19:46:25 +00:00
} else if ( ! strcasecmp ( var , " vm-keep-local-after-email " ) ) {
insert_db = switch_true ( val ) ;
} else if ( ! strcasecmp ( var , " vm-attach-file " ) ) {
email_attach = switch_true ( val ) ;
2009-10-01 22:43:44 +00:00
} else if ( ! strcasecmp ( var , " vm-convert-cmd " ) ) {
convert_cmd = switch_core_strdup ( pool , val ) ;
} else if ( ! strcasecmp ( var , " vm-convert-ext " ) ) {
convert_ext = switch_core_strdup ( pool , val ) ;
2008-09-26 19:48:55 +00:00
} else if ( ! strcasecmp ( var , " timezone " ) ) {
vm_timezone = switch_core_strdup ( pool , val ) ;
2008-07-17 19:46:25 +00:00
}
2010-02-06 03:38:24 +00:00
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Send mail is %d, var is %s\n", send_mail, var); */
2008-07-17 19:46:25 +00:00
}
2008-12-29 22:26:10 +00:00
2009-01-14 00:02:15 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Deliver VM to %s@%s \n " , myid , domain_name ) ;
2008-12-29 22:26:10 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( vm_storage_dir ) ) {
2008-08-28 05:02:18 +00:00
dir_path = switch_mprintf ( " %s%s%s " , vm_storage_dir , SWITCH_PATH_SEPARATOR , myid ) ;
2009-10-23 16:03:42 +00:00
} else if ( ! zstr ( profile - > storage_dir ) ) {
2008-11-07 17:36:08 +00:00
dir_path = switch_mprintf ( " %s%s%s%s%s " , profile - > storage_dir , SWITCH_PATH_SEPARATOR , domain_name , SWITCH_PATH_SEPARATOR , myid ) ;
2008-08-28 05:02:18 +00:00
} else {
2008-07-17 19:46:25 +00:00
dir_path = switch_mprintf ( " %s%svoicemail%s%s%s%s%s%s " , SWITCH_GLOBAL_dirs . storage_dir ,
SWITCH_PATH_SEPARATOR ,
SWITCH_PATH_SEPARATOR , profile - > name , SWITCH_PATH_SEPARATOR , domain_name , SWITCH_PATH_SEPARATOR , myid ) ;
}
if ( switch_dir_make_recursive ( dir_path , SWITCH_DEFAULT_DIR_PERMS , pool ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error creating %s \n " , dir_path ) ;
2008-09-08 21:56:07 +00:00
ret = SWITCH_STATUS_FALSE ;
2008-07-17 19:46:25 +00:00
goto failed ;
}
file_path = switch_mprintf ( " %s%smsg_%s_broadcast_%s " , dir_path , SWITCH_PATH_SEPARATOR , uuid_str , filename ) ;
if ( copy ) {
switch_file_copy ( path , file_path , SWITCH_FPROT_FILE_SOURCE_PERMS , pool ) ;
} else {
2010-02-06 03:38:24 +00:00
file_path = ( char * ) path ;
2008-07-17 19:46:25 +00:00
}
if ( ! message_len ) {
size_t len = 0 ;
if ( measure_file_len ( file_path , & len ) = = SWITCH_STATUS_SUCCESS ) {
message_len = len ;
}
}
if ( insert_db & & switch_file_exists ( file_path , pool ) = = SWITCH_STATUS_SUCCESS ) {
char * usql ;
2008-10-31 18:22:00 +00:00
switch_event_t * message_event ;
2010-02-06 03:38:24 +00:00
2008-10-31 18:22:00 +00:00
switch_event_create_subclass ( & message_event , SWITCH_EVENT_CUSTOM , VM_EVENT_MAINT ) ;
switch_event_add_header_string ( message_event , SWITCH_STACK_BOTTOM , " VM-Action " , " leave-message " ) ;
switch_event_add_header_string ( message_event , SWITCH_STACK_BOTTOM , " VM-User " , myid ) ;
switch_event_add_header_string ( message_event , SWITCH_STACK_BOTTOM , " VM-Domain " , domain_name ) ;
switch_event_add_header_string ( message_event , SWITCH_STACK_BOTTOM , " VM-Caller-ID-Name " , caller_id_name ) ;
switch_event_add_header_string ( message_event , SWITCH_STACK_BOTTOM , " VM-Caller-ID-Number " , caller_id_number ) ;
switch_event_add_header_string ( message_event , SWITCH_STACK_BOTTOM , " VM-File-Path " , file_path ) ;
switch_event_add_header_string ( message_event , SWITCH_STACK_BOTTOM , " VM-Flags " , read_flags ) ;
switch_event_add_header_string ( message_event , SWITCH_STACK_BOTTOM , " VM-Folder " , myfolder ) ;
switch_event_add_header ( message_event , SWITCH_STACK_BOTTOM , " VM-Message-Len " , " %u " , message_len ) ;
2009-01-25 21:23:07 +00:00
switch_event_add_header ( message_event , SWITCH_STACK_BOTTOM , " VM-Timestamp " , " %lu " , ( unsigned long ) switch_epoch_time_now ( NULL ) ) ;
2008-10-31 18:22:00 +00:00
switch_event_fire ( & message_event ) ;
2008-10-29 17:28:12 +00:00
2009-02-03 20:45:42 +00:00
usql = switch_mprintf ( " insert into voicemail_msgs(created_epoch, read_epoch, username, domain, uuid, cid_name, "
2010-01-13 01:32:01 +00:00
" cid_number, in_folder, file_path, message_len, flags, read_flags, forwarded_by) "
" values(%ld,0,'%q','%q','%q','%q','%q','%q','%q','%u','','%q','%q') " , ( long ) switch_epoch_time_now ( NULL ) ,
2008-07-17 19:46:25 +00:00
myid , domain_name , uuid_str , caller_id_name , caller_id_number ,
2010-01-13 01:32:01 +00:00
myfolder , file_path , message_len , read_flags , switch_str_nil ( forwarded_by ) ) ;
2008-09-08 21:56:07 +00:00
2008-07-17 19:46:25 +00:00
vm_execute_sql ( profile , usql , profile - > mutex ) ;
switch_safe_free ( usql ) ;
2008-08-28 05:28:05 +00:00
update_mwi ( profile , myid , domain_name , myfolder ) ;
2008-07-17 19:46:25 +00:00
}
2009-10-23 16:03:42 +00:00
if ( send_mail & & ! zstr ( vm_email ) & & switch_file_exists ( file_path , pool ) = = SWITCH_STATUS_SUCCESS ) {
2008-07-17 19:46:25 +00:00
switch_event_t * event ;
char * from ;
char * body ;
char * headers ;
char * header_string ;
2008-07-19 15:16:29 +00:00
char tmpvar [ 50 ] = " " ;
2008-07-17 19:46:25 +00:00
int total_new_messages = 0 ;
int total_saved_messages = 0 ;
int total_new_urgent_messages = 0 ;
int total_saved_urgent_messages = 0 ;
char * p ;
2008-08-28 05:17:02 +00:00
switch_time_t l_duration = 0 ;
2008-07-17 19:46:25 +00:00
switch_core_time_duration_t duration ;
char duration_str [ 80 ] ;
switch_time_exp_t tm ;
char date [ 80 ] = " " ;
switch_size_t retsize ;
message_count ( profile , myid , domain_name , myfolder , & total_new_messages , & total_saved_messages ,
& total_new_urgent_messages , & total_saved_urgent_messages ) ;
2009-10-23 16:03:42 +00:00
if ( zstr ( vm_timezone ) | | ( switch_strftime_tz ( vm_timezone , profile - > date_fmt , date , sizeof ( date ) , 0 ) ! = SWITCH_STATUS_SUCCESS ) ) {
2009-01-25 21:23:07 +00:00
switch_time_exp_lt ( & tm , switch_micro_time_now ( ) ) ;
2008-10-10 20:30:05 +00:00
switch_strftime ( date , & retsize , sizeof ( date ) , profile - > date_fmt , & tm ) ;
}
2008-07-17 19:46:25 +00:00
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_current_folder " , myfolder ) ;
2008-07-19 15:16:29 +00:00
switch_snprintf ( tmpvar , sizeof ( tmpvar ) , " %d " , total_new_messages ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_total_new_messages " , tmpvar ) ;
switch_snprintf ( tmpvar , sizeof ( tmpvar ) , " %d " , total_saved_messages ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_total_saved_messages " , tmpvar ) ;
switch_snprintf ( tmpvar , sizeof ( tmpvar ) , " %d " , total_new_urgent_messages ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_urgent_new_messages " , tmpvar ) ;
switch_snprintf ( tmpvar , sizeof ( tmpvar ) , " %d " , total_saved_urgent_messages ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_urgent_saved_messages " , tmpvar ) ;
2008-07-17 19:46:25 +00:00
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_account " , myid ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_domain " , domain_name ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_caller_id_number " , caller_id_number ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_caller_id_name " , caller_id_name ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_file_path " , file_path ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_read_flags " , read_flags ) ;
2008-10-10 20:30:05 +00:00
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_time " , date ) ;
2008-09-29 17:17:26 +00:00
2008-07-19 15:16:29 +00:00
switch_snprintf ( tmpvar , sizeof ( tmpvar ) , " %d " , priority ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_priority " , tmpvar ) ;
2008-07-17 19:46:25 +00:00
if ( vm_email ) {
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_email " , vm_email ) ;
}
if ( vm_notify_email ) {
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_notify_email " , vm_notify_email ) ;
}
2010-02-06 03:38:24 +00:00
l_duration = switch_time_make ( message_len , 0 ) ;
2008-07-17 19:46:25 +00:00
switch_core_measure_time ( l_duration , & duration ) ;
duration . day + = duration . yr * 365 ;
duration . hr + = duration . day * 24 ;
switch_snprintf ( duration_str , sizeof ( duration_str ) , " %.2u:%.2u:%.2u " , duration . hr , duration . min , duration . sec ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " voicemail_message_len " , duration_str ) ;
2009-10-23 16:03:42 +00:00
if ( zstr ( profile - > email_from ) ) {
2008-07-17 19:46:25 +00:00
from = switch_core_sprintf ( pool , " %s@%s " , myid , domain_name ) ;
} else {
2009-05-11 00:27:58 +00:00
from = switch_event_expand_headers ( params , profile - > email_from ) ;
2008-07-17 19:46:25 +00:00
}
if ( send_main ) {
2009-10-23 16:03:42 +00:00
if ( zstr ( profile - > email_headers ) ) {
2010-02-06 03:38:24 +00:00
headers = switch_mprintf ( " From: FreeSWITCH mod_voicemail <%s@%s> \n "
" Subject: Voicemail from %s %s \n X-Priority: %d " , myid , domain_name , caller_id_name , caller_id_number , priority ) ;
2008-07-17 19:46:25 +00:00
} else {
headers = switch_event_expand_headers ( params , profile - > email_headers ) ;
}
p = headers + ( strlen ( headers ) - 1 ) ;
if ( * p = = ' \n ' ) {
if ( * ( p - 1 ) = = ' \r ' ) {
p - - ;
}
* p = ' \0 ' ;
}
header_string = switch_core_sprintf ( pool , " %s \n X-Voicemail-Length: %u " , headers , message_len ) ;
switch_event_dup ( & event , params ) ;
if ( event ) {
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Message-Type " , " voicemail " ) ;
2008-07-17 19:46:25 +00:00
switch_event_fire ( & event ) ;
}
if ( profile - > email_body ) {
body = switch_event_expand_headers ( params , profile - > email_body ) ;
} else {
body = switch_mprintf ( " %u second Voicemail from %s %s " , message_len , caller_id_name , caller_id_number ) ;
}
if ( email_attach ) {
2009-10-01 22:43:44 +00:00
switch_simple_email ( vm_email , from , header_string , body , file_path , convert_cmd , convert_ext ) ;
2008-07-17 19:46:25 +00:00
} else {
2009-10-01 22:43:44 +00:00
switch_simple_email ( vm_email , from , header_string , body , NULL , NULL , NULL ) ;
2008-07-17 19:46:25 +00:00
}
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Sending message to %s \n " , vm_email ) ;
2010-02-06 03:38:24 +00:00
2009-07-02 04:44:27 +00:00
if ( body ! = profile - > email_body ) {
2010-02-06 03:38:24 +00:00
switch_safe_free ( body ) ;
2009-07-02 04:39:54 +00:00
}
2008-07-17 19:46:25 +00:00
if ( headers ! = profile - > email_headers ) {
switch_safe_free ( headers ) ;
}
}
if ( send_notify ) {
2009-10-23 16:03:42 +00:00
if ( zstr ( profile - > notify_email_headers ) ) {
2010-02-06 03:38:24 +00:00
headers = switch_mprintf ( " From: FreeSWITCH mod_voicemail <%s@%s> \n "
" Subject: Voicemail from %s %s \n X-Priority: %d " , myid , domain_name , caller_id_name , caller_id_number , priority ) ;
2008-07-17 19:46:25 +00:00
} else {
headers = switch_event_expand_headers ( params , profile - > notify_email_headers ) ;
}
p = headers + ( strlen ( headers ) - 1 ) ;
if ( * p = = ' \n ' ) {
if ( * ( p - 1 ) = = ' \r ' ) {
p - - ;
}
* p = ' \0 ' ;
}
header_string = switch_core_sprintf ( pool , " %s \n X-Voicemail-Length: %u " , headers , message_len ) ;
switch_event_dup ( & event , params ) ;
if ( event ) {
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Message-Type " , " voicemail-notify " ) ;
2008-07-17 19:46:25 +00:00
switch_event_fire ( & event ) ;
}
if ( profile - > notify_email_body ) {
body = switch_event_expand_headers ( params , profile - > notify_email_body ) ;
} else {
body = switch_mprintf ( " %u second Voicemail from %s %s " , message_len , caller_id_name , caller_id_number ) ;
}
2009-10-01 22:43:44 +00:00
switch_simple_email ( vm_notify_email , from , header_string , body , NULL , NULL , NULL ) ;
2008-07-17 19:46:25 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Sending notify message to %s \n " , vm_notify_email ) ;
2010-02-06 03:38:24 +00:00
2009-07-02 04:39:54 +00:00
if ( body ! = profile - > notify_email_body ) {
2010-02-06 03:38:24 +00:00
switch_safe_free ( body ) ;
2009-07-02 04:39:54 +00:00
}
2008-07-17 19:46:25 +00:00
if ( headers ! = profile - > notify_email_headers ) {
switch_safe_free ( headers ) ;
}
}
if ( ! insert_db ) {
if ( unlink ( file_path ) ! = 0 ) {
2008-10-11 06:19:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Failed to delete file [%s] \n " , file_path ) ;
2008-07-17 19:46:25 +00:00
}
}
}
2009-01-14 00:02:15 +00:00
failed :
2008-07-17 19:46:25 +00:00
switch_event_destroy ( & local_event ) ;
switch_safe_free ( dir_path ) ;
if ( file_path ! = path ) {
switch_safe_free ( file_path ) ;
}
2008-09-08 21:56:07 +00:00
return ret ;
2008-07-17 19:46:25 +00:00
}
static switch_status_t voicemail_inject ( const char * data )
{
vm_profile_t * profile ;
2009-09-03 18:21:15 +00:00
char * dup = NULL , * user = NULL , * domain = NULL , * profile_name = NULL ;
2008-07-29 17:32:30 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2008-12-29 22:26:10 +00:00
int isgroup = 0 , isall = 0 ;
2008-07-17 19:46:25 +00:00
int argc = 0 ;
2010-01-13 20:29:21 +00:00
char * argv [ 6 ] = { 0 } ;
2008-07-17 19:46:25 +00:00
char * box , * path , * cid_num , * cid_name ;
switch_memory_pool_t * pool = NULL ;
2010-01-13 01:32:01 +00:00
char * forwarded_by = NULL ;
2010-03-18 18:24:19 +00:00
char * read_flags = NORMAL_FLAG_STRING ;
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) ) {
2008-07-29 17:32:30 +00:00
status = SWITCH_STATUS_FALSE ;
goto end ;
}
2010-02-06 03:38:24 +00:00
2008-07-17 19:46:25 +00:00
dup = strdup ( data ) ;
switch_assert ( dup ) ;
if ( ( argc = switch_separate_string ( dup , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) < 2 ) {
2008-10-11 06:19:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Not enough args [%s] \n " , data ) ;
2008-08-28 02:21:21 +00:00
status = SWITCH_STATUS_FALSE ;
2008-07-17 19:46:25 +00:00
goto end ;
}
box = argv [ 0 ] ;
path = argv [ 1 ] ;
cid_num = argv [ 2 ] ? argv [ 2 ] : " anonymous " ;
cid_name = argv [ 3 ] ? argv [ 3 ] : " anonymous " ;
2010-01-13 01:32:01 +00:00
forwarded_by = argv [ 4 ] ;
2010-01-13 20:29:21 +00:00
if ( ! zstr ( argv [ 5 ] ) ) {
read_flags = argv [ 5 ] ;
}
2008-07-17 19:46:25 +00:00
user = box ;
2010-02-06 03:38:24 +00:00
2008-07-17 19:46:25 +00:00
if ( ( domain = strchr ( user , ' @ ' ) ) ) {
* domain + + = ' \0 ' ;
} else {
domain = user ;
}
2009-09-03 18:21:15 +00:00
if ( ( profile_name = strchr ( domain , ' @ ' ) ) ) {
* profile_name + + = ' \0 ' ;
} else {
profile_name = domain ;
}
2008-12-29 22:26:10 +00:00
if ( switch_stristr ( " group= " , user ) ) {
user + = 6 ;
isgroup + + ;
2008-07-17 19:46:25 +00:00
} else if ( user = = domain ) {
isall + + ;
}
2010-02-06 03:38:24 +00:00
2008-07-17 19:46:25 +00:00
if ( ! ( user & & domain ) ) {
2008-10-11 06:19:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid syntax [%s][%s] \n " , switch_str_nil ( user ) , switch_str_nil ( domain ) ) ;
2008-08-28 02:21:21 +00:00
status = SWITCH_STATUS_FALSE ;
2008-07-17 19:46:25 +00:00
goto end ;
}
2009-09-03 18:21:15 +00:00
if ( ! ( profile = get_profile ( profile_name ) ) ) {
if ( ! ( profile = get_profile ( domain ) ) ) {
profile = get_profile ( " default " ) ;
}
2008-07-17 19:46:25 +00:00
}
2010-02-06 03:38:24 +00:00
2008-07-17 19:46:25 +00:00
if ( ! profile ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Can't find profile \n " ) ;
2008-08-28 02:21:21 +00:00
status = SWITCH_STATUS_FALSE ;
2008-07-17 19:46:25 +00:00
} else {
switch_xml_t x_domain , xml_root ;
switch_event_t * my_params = NULL ;
switch_xml_t ut ;
2008-10-02 17:10:05 +00:00
switch_event_create ( & my_params , SWITCH_EVENT_REQUEST_PARAMS ) ;
2008-07-17 19:46:25 +00:00
switch_assert ( my_params ) ;
2008-12-29 22:26:10 +00:00
if ( isgroup ) {
switch_event_add_header_string ( my_params , SWITCH_STACK_BOTTOM , " group " , user ) ;
} else {
if ( isall ) {
switch_event_add_header_string ( my_params , SWITCH_STACK_BOTTOM , " user " , " _all_ " ) ;
} else {
switch_event_add_header_string ( my_params , SWITCH_STACK_BOTTOM , " user " , user ) ;
}
}
2010-01-13 01:32:01 +00:00
if ( forwarded_by ) {
switch_event_add_header_string ( my_params , SWITCH_STACK_BOTTOM , " Forwarded-By " , forwarded_by ) ;
}
2008-07-17 19:46:25 +00:00
switch_event_add_header_string ( my_params , SWITCH_STACK_BOTTOM , " domain " , domain ) ;
switch_event_add_header_string ( my_params , SWITCH_STACK_BOTTOM , " purpose " , " publish-vm " ) ;
2010-02-06 03:38:24 +00:00
2008-07-17 19:46:25 +00:00
if ( switch_xml_locate_domain ( domain , my_params , & xml_root , & x_domain ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Cannot locate domain %s \n " , domain ) ;
2008-08-28 02:21:21 +00:00
status = SWITCH_STATUS_FALSE ;
2008-07-17 19:46:25 +00:00
switch_event_destroy ( & my_params ) ;
goto end ;
}
2010-02-06 03:38:24 +00:00
2008-07-17 19:46:25 +00:00
switch_event_destroy ( & my_params ) ;
switch_core_new_memory_pool ( & pool ) ;
2010-02-06 03:38:24 +00:00
2008-12-29 22:26:10 +00:00
if ( isgroup ) {
switch_xml_t group = NULL , groups = NULL , users = NULL ;
if ( ( groups = switch_xml_child ( x_domain , " groups " ) ) ) {
if ( ( group = switch_xml_find_child_multi ( groups , " group " , " name " , user , NULL ) ) ) {
if ( ( users = switch_xml_child ( group , " users " ) ) ) {
for ( ut = switch_xml_child ( users , " user " ) ; ut ; ut = ut - > next ) {
const char * type = switch_xml_attr_soft ( ut , " type " ) ;
2010-02-06 03:38:24 +00:00
2008-12-29 22:26:10 +00:00
if ( ! strcasecmp ( type , " pointer " ) ) {
const char * uname = switch_xml_attr_soft ( ut , " id " ) ;
switch_xml_t ux ;
if ( switch_xml_locate_user_in_domain ( uname , x_domain , & ux , NULL ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_create ( & my_params , SWITCH_EVENT_REQUEST_PARAMS ) ;
2010-02-06 03:38:24 +00:00
status =
deliver_vm ( profile , ux , domain , path , 0 , read_flags , my_params , pool , cid_name , cid_num , forwarded_by ,
SWITCH_TRUE ) ;
2008-12-29 22:26:10 +00:00
switch_event_destroy ( & my_params ) ;
}
continue ;
}
2010-02-06 03:38:24 +00:00
2008-12-29 22:26:10 +00:00
switch_event_create ( & my_params , SWITCH_EVENT_REQUEST_PARAMS ) ;
2010-01-13 20:29:21 +00:00
status = deliver_vm ( profile , ut , domain , path , 0 , read_flags , my_params , pool , cid_name , cid_num , forwarded_by , SWITCH_TRUE ) ;
2008-12-29 22:26:10 +00:00
switch_event_destroy ( & my_params ) ;
}
}
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Cannot locate group %s \n " , user ) ;
}
}
} else if ( isall ) {
switch_xml_t group = NULL , groups = NULL , users = NULL ;
if ( ( groups = switch_xml_child ( x_domain , " groups " ) ) ) {
for ( group = switch_xml_child ( groups , " group " ) ; group ; group = group - > next ) {
if ( ( users = switch_xml_child ( group , " users " ) ) ) {
for ( ut = switch_xml_child ( users , " user " ) ; ut ; ut = ut - > next ) {
const char * type = switch_xml_attr_soft ( ut , " type " ) ;
2010-02-06 03:38:24 +00:00
2008-12-29 22:26:10 +00:00
if ( ! strcasecmp ( type , " pointer " ) ) {
continue ;
}
switch_event_create ( & my_params , SWITCH_EVENT_REQUEST_PARAMS ) ;
2010-01-13 20:29:21 +00:00
status = deliver_vm ( profile , ut , domain , path , 0 , read_flags , my_params , pool , cid_name , cid_num , forwarded_by , SWITCH_TRUE ) ;
2008-12-29 22:26:10 +00:00
switch_event_destroy ( & my_params ) ;
}
}
}
}
2010-02-06 03:38:24 +00:00
2008-12-29 22:26:10 +00:00
} else {
switch_xml_t x_group = NULL ;
if ( ( status = switch_xml_locate_user_in_domain ( user , x_domain , & ut , & x_group ) ) = = SWITCH_STATUS_SUCCESS ) {
2008-10-02 17:10:05 +00:00
switch_event_create ( & my_params , SWITCH_EVENT_REQUEST_PARAMS ) ;
2010-01-13 20:29:21 +00:00
status = deliver_vm ( profile , ut , domain , path , 0 , read_flags , my_params , pool , cid_name , cid_num , forwarded_by , SWITCH_TRUE ) ;
2008-09-08 21:56:07 +00:00
switch_event_destroy ( & my_params ) ;
} else {
status = SWITCH_STATUS_FALSE ;
}
2008-07-17 19:46:25 +00:00
}
2009-06-20 19:55:30 +00:00
profile_rwunlock ( profile ) ;
2010-02-06 03:38:24 +00:00
2008-07-17 19:46:25 +00:00
switch_core_destroy_memory_pool ( & pool ) ;
switch_xml_free ( xml_root ) ;
}
2009-01-14 00:02:15 +00:00
end :
2008-07-17 19:46:25 +00:00
switch_safe_free ( dup ) ;
return status ;
}
2009-04-25 14:16:32 +00:00
static switch_status_t voicemail_leave_main ( switch_core_session_t * session , vm_profile_t * profile , const char * domain_name , const char * id )
2007-10-12 03:28:59 +00:00
{
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-12-26 17:37:13 +00:00
char sql [ 256 ] ;
prefs_callback_t cbt ;
char * uuid = switch_core_session_get_uuid ( session ) ;
char * file_path = NULL ;
char * dir_path = NULL ;
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2008-01-28 07:26:10 +00:00
switch_caller_profile_t * caller_profile = switch_channel_get_caller_profile ( channel ) ;
2007-12-26 17:37:13 +00:00
switch_file_handle_t fh = { 0 } ;
switch_input_args_t args = { 0 } ;
2008-06-04 22:52:37 +00:00
char * vm_email = NULL ;
char * vm_notify_email = NULL ;
2007-12-26 17:37:13 +00:00
int send_mail = 0 ;
cc_t cc = { 0 } ;
char * read_flags = NORMAL_FLAG_STRING ;
int priority = 3 ;
int email_attach = 1 ;
char buf [ 2 ] ;
2008-11-26 21:04:21 +00:00
char key_buf [ 80 ] ;
2007-12-26 17:37:13 +00:00
char * greet_path = NULL ;
2007-11-01 11:28:26 +00:00
const char * voicemail_greeting_number = NULL ;
2007-12-26 17:37:13 +00:00
switch_size_t message_len = 0 ;
2007-11-26 23:41:00 +00:00
switch_time_exp_t tm ;
char date [ 80 ] = " " ;
switch_size_t retsize ;
2009-01-25 21:23:07 +00:00
switch_time_t ts = switch_micro_time_now ( ) ;
2008-08-28 05:02:18 +00:00
char * vm_storage_dir = NULL ;
2008-12-18 22:53:01 +00:00
char * record_macro = VM_RECORD_MESSAGE_MACRO ;
2008-06-03 22:01:26 +00:00
int send_main = 0 ;
int send_notify = 0 ;
int insert_db = 1 ;
2008-12-04 15:22:43 +00:00
const char * read_id = NULL ;
2008-06-27 15:01:14 +00:00
const char * caller_id_name = NULL ;
const char * caller_id_number = NULL ;
2010-02-15 17:40:13 +00:00
switch_xml_t x_user = NULL , x_params = NULL , x_param = NULL ;
2008-07-17 19:46:25 +00:00
switch_event_t * vars = NULL ;
2008-07-18 21:16:52 +00:00
const char * vm_cc = NULL , * vtmp , * vm_ext = NULL ;
2009-05-14 22:47:44 +00:00
int disk_quota = 0 ;
2009-09-25 21:27:00 +00:00
switch_bool_t skip_greeting = switch_true ( switch_channel_get_variable ( channel , " skip_greeting " ) ) ;
switch_bool_t skip_instructions = switch_true ( switch_channel_get_variable ( channel , " skip_instructions " ) ) ;
switch_channel_set_variable ( channel , " skip_greeting " , NULL ) ;
switch_channel_set_variable ( channel , " skip_instructions " , NULL ) ;
2010-02-06 03:38:24 +00:00
2008-06-27 15:01:14 +00:00
if ( ! ( caller_id_name = switch_channel_get_variable ( channel , " effective_caller_id_name " ) ) ) {
caller_id_name = caller_profile - > caller_id_name ;
}
if ( ! ( caller_id_number = switch_channel_get_variable ( channel , " effective_caller_id_number " ) ) ) {
caller_id_number = caller_profile - > caller_id_number ;
}
2007-12-26 17:37:13 +00:00
memset ( & cbt , 0 , sizeof ( cbt ) ) ;
2007-12-15 04:58:44 +00:00
if ( id ) {
2007-12-26 17:37:13 +00:00
int ok = 1 ;
2009-05-11 22:28:02 +00:00
switch_event_t * locate_params = NULL ;
2007-12-26 17:37:13 +00:00
const char * email_addr = NULL ;
2010-02-15 17:40:13 +00:00
2008-05-27 04:54:52 +00:00
2009-05-11 22:28:02 +00:00
switch_event_create ( & locate_params , SWITCH_EVENT_REQUEST_PARAMS ) ;
switch_assert ( locate_params ) ;
2008-05-27 04:54:52 +00:00
2010-02-15 17:40:13 +00:00
if ( switch_xml_locate_user_merged ( " id " , id , domain_name , switch_channel_get_variable ( channel , " network_addr " ) ,
& x_user , locate_params ) = = SWITCH_STATUS_SUCCESS ) {
2009-05-18 17:34:35 +00:00
id = switch_core_session_strdup ( session , switch_xml_attr ( x_user , " id " ) ) ;
2010-02-05 20:05:22 +00:00
2008-05-27 04:54:52 +00:00
if ( ( x_params = switch_xml_child ( x_user , " params " ) ) ) {
for ( x_param = switch_xml_child ( x_params , " param " ) ; x_param ; x_param = x_param - > next ) {
const char * var = switch_xml_attr_soft ( x_param , " name " ) ;
const char * val = switch_xml_attr_soft ( x_param , " value " ) ;
if ( ! strcasecmp ( var , " vm-mailto " ) ) {
2008-06-04 22:52:37 +00:00
vm_email = switch_core_session_strdup ( session , val ) ;
2008-06-03 22:01:26 +00:00
} else if ( ! strcasecmp ( var , " vm-notify-mailto " ) ) {
2008-06-04 22:52:37 +00:00
vm_notify_email = switch_core_session_strdup ( session , val ) ;
2008-05-27 04:54:52 +00:00
} else if ( ! strcasecmp ( var , " email-addr " ) ) {
2008-06-03 22:01:26 +00:00
email_addr = switch_core_session_strdup ( session , val ) ;
2008-12-03 15:45:20 +00:00
} else if ( ! strcasecmp ( var , " vm-email-all-messages " ) & & ( send_main = switch_true ( val ) ) ) {
2008-08-26 15:40:30 +00:00
send_mail + + ;
2008-08-28 05:02:18 +00:00
} else if ( ! strcasecmp ( var , " storage-dir " ) ) {
vm_storage_dir = switch_core_session_strdup ( session , val ) ;
2008-12-03 15:45:20 +00:00
} else if ( ! strcasecmp ( var , " vm-notify-email-all-messages " ) & & ( send_notify = switch_true ( val ) ) ) {
2008-08-26 15:40:30 +00:00
send_mail + + ;
2008-06-03 22:01:26 +00:00
} else if ( ! strcasecmp ( var , " vm-keep-local-after-email " ) ) {
insert_db = switch_true ( val ) ;
2008-05-27 04:54:52 +00:00
} else if ( ! strcasecmp ( var , " vm-attach-file " ) ) {
email_attach = switch_true ( val ) ;
2009-05-14 22:47:44 +00:00
} else if ( ! strcasecmp ( var , " vm-disk-quota " ) ) {
disk_quota = atoi ( val ) ;
2008-12-04 15:22:43 +00:00
} else if ( ! strcasecmp ( var , " vm-alternate-greet-id " ) ) {
read_id = switch_core_session_strdup ( session , val ) ;
2010-02-05 08:27:20 +00:00
} else if ( ! strcasecmp ( var , " vm-message-ext " ) ) {
vm_ext = switch_core_session_strdup ( session , val ) ;
2007-12-26 17:37:13 +00:00
}
}
2008-05-27 04:54:52 +00:00
}
2007-12-26 17:37:13 +00:00
2009-10-23 16:03:42 +00:00
if ( send_main & & zstr ( vm_email ) & & ! zstr ( email_addr ) ) {
2008-06-04 22:52:37 +00:00
vm_email = switch_core_session_strdup ( session , email_addr ) ;
2009-10-23 16:03:42 +00:00
if ( zstr ( vm_email ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " No email address, not going to send email. \n " ) ;
2008-06-03 22:01:26 +00:00
send_main = 0 ;
}
}
2009-10-23 16:03:42 +00:00
if ( send_notify & & zstr ( vm_notify_email ) ) {
2008-06-04 22:52:37 +00:00
vm_notify_email = vm_email ;
2009-10-23 16:03:42 +00:00
if ( zstr ( vm_notify_email ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " No notify email address, not going to notify. \n " ) ;
2008-06-03 22:01:26 +00:00
send_notify = 0 ;
}
}
2010-02-06 03:38:24 +00:00
2008-06-03 22:01:26 +00:00
if ( send_mail & & ( ! ( send_main | | send_notify ) ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
" Falling back to leaving message locally due to too many misconfiguration. \n " ) ;
2008-06-03 22:01:26 +00:00
send_mail = 0 ;
insert_db = 1 ;
2008-05-27 04:54:52 +00:00
}
2007-12-26 17:37:13 +00:00
2008-06-03 22:01:26 +00:00
if ( send_notify & & ! send_main ) {
insert_db = 1 ;
}
2010-02-06 03:38:24 +00:00
2007-12-26 17:37:13 +00:00
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Can't find user [%s@%s] \n " , id , domain_name ) ;
2007-12-26 17:37:13 +00:00
ok = 0 ;
}
2007-10-12 03:28:59 +00:00
2009-05-11 22:28:02 +00:00
switch_event_destroy ( & locate_params ) ;
2010-02-06 03:38:24 +00:00
2007-12-26 17:37:13 +00:00
if ( ! ok ) {
goto end ;
}
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( vm_storage_dir ) ) {
2008-08-28 05:02:18 +00:00
dir_path = switch_core_session_sprintf ( session , " %s%s%s " , vm_storage_dir , SWITCH_PATH_SEPARATOR , id ) ;
2009-10-23 16:03:42 +00:00
} else if ( ! zstr ( profile - > storage_dir ) ) {
2008-11-07 17:36:08 +00:00
dir_path = switch_core_session_sprintf ( session , " %s%s%s%s%s " , profile - > storage_dir , SWITCH_PATH_SEPARATOR , domain_name , SWITCH_PATH_SEPARATOR , id ) ;
2008-08-28 05:02:18 +00:00
} else {
dir_path = switch_core_session_sprintf ( session , " %s%svoicemail%s%s%s%s%s%s " , SWITCH_GLOBAL_dirs . storage_dir ,
SWITCH_PATH_SEPARATOR ,
SWITCH_PATH_SEPARATOR , profile - > name , SWITCH_PATH_SEPARATOR , domain_name , SWITCH_PATH_SEPARATOR , id ) ;
}
if ( switch_dir_make_recursive ( dir_path , SWITCH_DEFAULT_DIR_PERMS , switch_core_session_get_pool ( session ) ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Error creating %s \n " , dir_path ) ;
2008-08-28 05:02:18 +00:00
goto end ;
}
2008-05-27 04:54:52 +00:00
switch_snprintf ( sql , sizeof ( sql ) , " select * from voicemail_prefs where username='%s' and domain='%s' " , id , domain_name ) ;
2007-12-26 17:37:13 +00:00
vm_execute_sql_callback ( profile , profile - > mutex , sql , prefs_callback , & cbt ) ;
2010-02-05 08:27:20 +00:00
if ( ! vm_ext ) {
vm_ext = profile - > file_ext ;
}
2008-07-18 21:16:52 +00:00
if ( ( vtmp = switch_channel_get_variable ( channel , " vm_message_ext " ) ) ) {
vm_ext = vtmp ;
}
file_path = switch_mprintf ( " %s%smsg_%s.%s " , dir_path , SWITCH_PATH_SEPARATOR , uuid , vm_ext ) ;
2007-12-26 17:37:13 +00:00
if ( ( voicemail_greeting_number = switch_channel_get_variable ( channel , " voicemail_greeting_number " ) ) ) {
int num = atoi ( voicemail_greeting_number ) ;
2008-03-07 23:34:14 +00:00
if ( num > 0 & & num < = VM_MAX_GREETINGS ) {
2007-12-26 17:37:13 +00:00
greet_path = switch_mprintf ( " %s%sgreeting_%d.%s " , dir_path , SWITCH_PATH_SEPARATOR , num , profile - > file_ext ) ;
}
2008-12-03 15:45:20 +00:00
} else if ( ! ( greet_path = ( char * ) switch_channel_get_variable ( channel , " voicemail_greeting_path " ) ) ) {
2007-12-26 17:37:13 +00:00
greet_path = cbt . greeting_path ;
}
2010-02-06 03:38:24 +00:00
greet :
2009-09-25 21:27:00 +00:00
if ( ! skip_greeting ) {
memset ( buf , 0 , sizeof ( buf ) ) ;
args . input_callback = cancel_on_dtmf ;
args . buf = buf ;
args . buflen = sizeof ( buf ) ;
2007-12-26 17:37:13 +00:00
2009-09-25 21:27:00 +00:00
switch_ivr_sleep ( session , 100 , SWITCH_TRUE , NULL ) ;
2009-03-03 14:21:26 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( greet_path ) ) {
2007-12-26 17:37:13 +00:00
memset ( buf , 0 , sizeof ( buf ) ) ;
2009-09-25 21:27:00 +00:00
TRY_CODE ( switch_ivr_play_file ( session , NULL , greet_path , & args ) ) ;
} else {
2009-10-23 16:03:42 +00:00
if ( ! zstr ( cbt . name_path ) ) {
2009-09-25 21:27:00 +00:00
memset ( buf , 0 , sizeof ( buf ) ) ;
TRY_CODE ( switch_ivr_play_file ( session , NULL , cbt . name_path , & args ) ) ;
}
if ( * buf = = ' \0 ' ) {
if ( ! read_id ) {
if ( ! ( read_id = switch_channel_get_variable ( channel , " voicemail_alternate_greet_id " ) ) ) {
read_id = id ;
}
2008-12-04 15:22:43 +00:00
}
2009-09-25 21:27:00 +00:00
memset ( buf , 0 , sizeof ( buf ) ) ;
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_PLAY_GREETING_MACRO , read_id , NULL , & args ) ) ;
2008-10-02 15:13:53 +00:00
}
2007-12-26 17:37:13 +00:00
}
2010-02-06 03:38:24 +00:00
if ( * buf ! = ' \0 ' ) {
greet_key_press :
if ( switch_stristr ( buf , profile - > login_keys ) ) {
voicemail_check_main ( session , profile , domain_name , id , 0 ) ;
} else if ( ! strcasecmp ( buf , profile - > operator_key ) & & ! zstr ( profile - > operator_key ) ) {
int argc ;
char * argv [ 4 ] ;
char * mycmd ;
if ( ! zstr ( profile - > operator_ext ) & & ( mycmd = switch_core_session_strdup ( session , profile - > operator_ext ) ) ) {
argc = switch_separate_string ( mycmd , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
if ( argc > = 1 & & argc < = 4 ) {
switch_ivr_session_transfer ( session , argv [ 0 ] , argv [ 1 ] , argv [ 2 ] ) ;
/* the application still runs after we leave it so we need to make sure that we don't do anything evil */
send_mail = 0 ;
goto end ;
}
}
} else if ( ! strcasecmp ( buf , profile - > vmain_key ) & & ! zstr ( profile - > vmain_key ) ) {
int argc ;
char * argv [ 4 ] ;
char * mycmd ;
if ( ! zstr ( profile - > vmain_ext ) & & ( mycmd = switch_core_session_strdup ( session , profile - > vmain_ext ) ) ) {
argc = switch_separate_string ( mycmd , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
if ( argc > = 1 & & argc < = 4 ) {
switch_ivr_session_transfer ( session , argv [ 0 ] , argv [ 1 ] , argv [ 2 ] ) ;
/* the application still runs after we leave it so we need to make sure that we don't do anything evil */
send_mail = 0 ;
goto end ;
}
}
2009-09-25 21:27:00 +00:00
} else if ( * profile - > skip_greet_key & & ! strcasecmp ( buf , profile - > skip_greet_key ) ) {
skip_instructions = SWITCH_TRUE ;
} else {
goto greet ;
2007-12-26 17:37:13 +00:00
}
}
}
2007-10-23 15:44:04 +00:00
2009-09-25 21:27:00 +00:00
if ( skip_instructions ) {
record_macro = NULL ;
}
2009-05-14 22:47:44 +00:00
if ( disk_quota ) {
2009-05-19 20:24:53 +00:00
callback_t callback = { 0 } ;
char sqlstmt [ 256 ] ;
2010-02-06 03:38:24 +00:00
char disk_usage [ 256 ] = " " ;
2009-05-14 22:47:44 +00:00
2009-05-19 20:24:53 +00:00
callback . buf = disk_usage ;
callback . len = sizeof ( disk_usage ) ;
2009-05-14 22:47:44 +00:00
2010-02-06 03:38:24 +00:00
switch_snprintf ( sqlstmt , sizeof ( sqlstmt ) , " select sum(message_len) from voicemail_msgs where username='%s' and domain='%s' " , id , domain_name ) ;
2009-10-14 21:42:33 +00:00
vm_execute_sql_callback ( profile , profile - > mutex , sqlstmt , sql2str_callback , & callback ) ;
2009-05-14 22:47:44 +00:00
if ( atoi ( disk_usage ) > = disk_quota ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Voicemail disk quota is exceeded for %s \n " , id ) ;
2009-05-14 22:47:44 +00:00
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_DISK_QUOTA_EXCEEDED_MACRO , NULL , NULL , NULL ) ) ;
goto end ;
}
}
2007-12-15 04:58:44 +00:00
memset ( & fh , 0 , sizeof ( fh ) ) ;
2007-12-26 17:37:13 +00:00
args . input_callback = control_playback ;
memset ( & cc , 0 , sizeof ( cc ) ) ;
cc . profile = profile ;
cc . fh = & fh ;
cc . noexit = 1 ;
args . buf = & cc ;
2007-10-12 03:28:59 +00:00
2009-07-02 04:39:54 +00:00
switch_channel_set_variable_printf ( channel , " RECORD_ARTIST " , " %s (%s) " , caller_id_name , caller_id_number ) ;
2007-10-12 03:28:59 +00:00
2007-11-26 23:41:00 +00:00
switch_time_exp_lt ( & tm , ts ) ;
2008-10-12 21:51:51 +00:00
switch_strftime_nocheck ( date , & retsize , sizeof ( date ) , " %Y-%m-%d %T " , & tm ) ;
2007-12-26 17:37:13 +00:00
switch_channel_set_variable ( channel , " RECORD_DATE " , date ) ;
switch_channel_set_variable ( channel , " RECORD_SOFTWARE " , " FreeSWITCH " ) ;
switch_channel_set_variable ( channel , " RECORD_TITLE " , profile - > record_title ) ;
switch_channel_set_variable ( channel , " RECORD_COMMENT " , profile - > record_comment ) ;
switch_channel_set_variable ( channel , " RECORD_COPYRIGHT " , profile - > record_copyright ) ;
2008-11-26 21:04:21 +00:00
switch_snprintf ( key_buf , sizeof ( key_buf ) , " %s:%s " , profile - > operator_key , profile - > vmain_key ) ;
memset ( buf , 0 , sizeof ( buf ) ) ;
2008-12-18 22:53:01 +00:00
status = create_file ( session , profile , record_macro , file_path , & message_len , SWITCH_TRUE , key_buf , buf ) ;
2007-12-26 17:37:13 +00:00
2008-09-23 20:31:49 +00:00
if ( ( status = = SWITCH_STATUS_NOTFOUND ) ) {
goto end ;
}
2008-11-26 21:04:21 +00:00
if ( buf [ 0 ] ) {
goto greet_key_press ;
}
2007-12-26 17:37:13 +00:00
if ( ( status = = SWITCH_STATUS_SUCCESS | | status = = SWITCH_STATUS_BREAK ) & & switch_channel_ready ( channel ) ) {
2008-11-26 21:04:21 +00:00
char input [ 10 ] = " " , term = 0 ;
2007-12-26 17:37:13 +00:00
2008-05-27 04:54:52 +00:00
switch_snprintf ( key_buf , sizeof ( key_buf ) , " %s:%s " , profile - > urgent_key , profile - > terminator_key ) ;
2007-12-26 17:37:13 +00:00
2010-02-06 03:38:24 +00:00
( void ) vm_macro_get ( session , VM_RECORD_URGENT_CHECK_MACRO , key_buf , input , sizeof ( input ) , 1 , " " , & term , profile - > digit_timeout ) ;
2007-12-26 17:37:13 +00:00
if ( * profile - > urgent_key = = * input ) {
read_flags = URGENT_FLAG_STRING ;
priority = 1 ;
2010-02-06 03:38:24 +00:00
( void ) switch_ivr_phrase_macro ( session , VM_ACK_MACRO , " marked-urgent " , NULL , NULL ) ;
2007-12-26 17:37:13 +00:00
} else {
2010-02-06 03:38:24 +00:00
( void ) switch_ivr_phrase_macro ( session , VM_ACK_MACRO , " saved " , NULL , NULL ) ;
2007-12-26 17:37:13 +00:00
}
}
2010-02-06 03:38:24 +00:00
2010-02-05 20:05:22 +00:00
if ( x_user ) {
2009-03-31 13:14:16 +00:00
switch_channel_get_variables ( channel , & vars ) ;
2010-02-06 03:38:24 +00:00
status = deliver_vm ( profile , x_user , domain_name , file_path , message_len , read_flags , vars ,
2010-01-13 01:32:01 +00:00
switch_core_session_get_pool ( session ) , caller_id_name , caller_id_number , NULL , SWITCH_FALSE ) ;
2009-03-31 13:14:16 +00:00
switch_event_destroy ( & vars ) ;
if ( status = = SWITCH_STATUS_SUCCESS ) {
if ( ( vm_cc = switch_channel_get_variable ( channel , " vm_cc " ) ) ) {
2010-02-06 03:38:24 +00:00
char * cmd = switch_core_session_sprintf ( session , " %s %s %s %s %s@%s %s " ,
2010-01-13 20:29:21 +00:00
vm_cc , file_path , caller_id_number , caller_id_name , id , domain_name , read_flags ) ;
2010-02-06 03:38:24 +00:00
2009-03-31 13:14:16 +00:00
if ( voicemail_inject ( cmd ) = = SWITCH_STATUS_SUCCESS ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Sent Carbon Copy to %s \n " , vm_cc ) ;
2009-03-31 13:14:16 +00:00
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Failed to Carbon Copy to %s \n " , vm_cc ) ;
2009-03-31 13:14:16 +00:00
}
2008-09-08 21:56:07 +00:00
}
2009-03-31 13:14:16 +00:00
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Failed to deliver message \n " ) ;
2009-03-31 13:14:16 +00:00
TRY_CODE ( switch_ivr_phrase_macro ( session , VM_ACK_MACRO , " deleted " , NULL , NULL ) ) ;
2008-07-29 17:42:55 +00:00
}
2009-04-02 16:01:51 +00:00
2007-12-26 17:37:13 +00:00
}
2009-04-02 16:01:51 +00:00
2009-01-14 00:02:15 +00:00
end :
2007-12-26 17:37:13 +00:00
2010-02-05 20:05:22 +00:00
if ( x_user ) {
switch_xml_free ( x_user ) ;
x_user = NULL ;
2007-12-26 17:37:13 +00:00
}
switch_safe_free ( file_path ) ;
2007-10-12 03:28:59 +00:00
2007-12-26 17:37:13 +00:00
if ( switch_channel_ready ( channel ) ) {
status = switch_ivr_phrase_macro ( session , VM_GOODBYE_MACRO , NULL , NULL , NULL ) ;
}
2007-10-12 03:28:59 +00:00
2007-12-26 17:37:13 +00:00
return status ;
2007-10-12 03:28:59 +00:00
}
# define VM_DESC "voicemail"
# define VM_USAGE "[check|auth] <profile_name> <domain_name> [<id>]"
SWITCH_STANDARD_APP ( voicemail_function )
{
int argc = 0 ;
2007-10-17 21:26:33 +00:00
char * argv [ 6 ] = { 0 } ;
2007-10-12 03:28:59 +00:00
char * mydata = NULL ;
2010-02-06 03:38:24 +00:00
vm_profile_t * profile = NULL ;
2007-12-26 17:37:13 +00:00
const char * profile_name = NULL ;
const char * domain_name = NULL ;
const char * id = NULL ;
const char * auth_var = NULL ;
int x = 0 , check = 0 , auth = 0 ;
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-12-26 17:37:13 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) ) {
2007-12-26 17:37:13 +00:00
mydata = switch_core_session_strdup ( session , data ) ;
argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
}
for ( ; ; ) {
if ( argv [ x ] & & ! strcasecmp ( argv [ x ] , " check " ) ) {
check + + ;
x + + ;
} else if ( argv [ x ] & & ! strcasecmp ( argv [ x ] , " auth " ) ) {
auth + + ;
x + + ;
} else {
break ;
}
}
if ( argv [ x ] ) {
profile_name = argv [ x + + ] ;
}
if ( argv [ x ] ) {
domain_name = argv [ x + + ] ;
}
if ( argv [ x ] ) {
id = argv [ x + + ] ;
}
2007-10-12 03:28:59 +00:00
2007-12-15 04:58:44 +00:00
if ( ( auth_var = switch_channel_get_variable ( channel , " voicemail_authorized " ) ) & & switch_true ( auth_var ) ) {
2007-12-26 17:37:13 +00:00
auth = 1 ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( profile_name ) ) {
2007-12-26 17:37:13 +00:00
profile_name = switch_channel_get_variable ( channel , " voicemail_profile_name " ) ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( domain_name ) ) {
2007-12-26 17:37:13 +00:00
domain_name = switch_channel_get_variable ( channel , " voicemail_domain_name " ) ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( id ) ) {
2007-12-26 17:37:13 +00:00
id = switch_channel_get_variable ( channel , " voicemail_id " ) ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( profile_name ) | | zstr ( domain_name ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Error Usage: %s \n " , VM_USAGE ) ;
2007-12-26 17:37:13 +00:00
return ;
}
2009-04-25 14:16:32 +00:00
if ( ! ( profile = get_profile ( profile_name ) ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Error invalid profile %s \n " , profile_name ) ;
2009-04-25 14:16:32 +00:00
return ;
}
2007-12-26 17:37:13 +00:00
if ( check ) {
2009-04-25 14:16:32 +00:00
voicemail_check_main ( session , profile , domain_name , id , auth ) ;
2007-12-26 17:37:13 +00:00
} else {
2009-04-25 14:16:32 +00:00
voicemail_leave_main ( session , profile , domain_name , id ) ;
2007-12-26 17:37:13 +00:00
}
2009-04-25 14:16:32 +00:00
2009-06-20 19:55:30 +00:00
profile_rwunlock ( profile ) ;
2010-02-06 03:38:24 +00:00
2007-10-12 03:28:59 +00:00
}
2009-05-12 04:58:32 +00:00
# define BOXCOUNT_SYNTAX "[profile / ]<user>@<domain>[|[new|saved|new-urgent|saved-urgent|all]]"
2008-05-17 00:33:34 +00:00
SWITCH_STANDARD_API ( boxcount_api_function )
{
char * dup ;
2009-05-12 04:58:32 +00:00
const char * how = " new " ;
2008-05-17 00:33:34 +00:00
int total_new_messages = 0 ;
int total_saved_messages = 0 ;
int total_new_urgent_messages = 0 ;
int total_saved_urgent_messages = 0 ;
2009-05-12 04:58:32 +00:00
vm_profile_t * profile ;
char * id , * domain , * p , * profilename = NULL ;
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( cmd ) ) {
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " %d " , 0 ) ;
2009-05-12 04:58:32 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2008-05-17 00:33:34 +00:00
2009-05-12 04:58:32 +00:00
id = dup = strdup ( cmd ) ;
2010-02-06 03:38:24 +00:00
2009-05-12 04:58:32 +00:00
if ( ( p = strchr ( dup , ' / ' ) ) ) {
* p + + = ' \0 ' ;
id = p ;
profilename = dup ;
}
2010-02-06 03:38:24 +00:00
2009-05-12 04:58:32 +00:00
if ( ! strncasecmp ( id , " sip: " , 4 ) ) {
id + = 4 ;
}
2008-05-17 00:33:34 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( id ) ) {
2009-05-12 04:58:32 +00:00
stream - > write_function ( stream , " %d " , 0 ) ;
goto done ;
}
2008-05-17 00:33:34 +00:00
2009-05-12 04:58:32 +00:00
if ( ( domain = strchr ( id , ' @ ' ) ) ) {
* domain + + = ' \0 ' ;
if ( ( p = strchr ( domain , ' | ' ) ) ) {
* p + + = ' \0 ' ;
how = p ;
2008-05-17 00:33:34 +00:00
}
2008-05-27 04:54:52 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( profilename ) ) {
2009-05-12 04:58:32 +00:00
if ( ( profile = get_profile ( profilename ) ) ) {
message_count ( profile , id , domain , " inbox " , & total_new_messages , & total_saved_messages ,
& total_new_urgent_messages , & total_saved_urgent_messages ) ;
2009-06-20 19:55:30 +00:00
profile_rwunlock ( profile ) ;
2009-05-12 04:58:32 +00:00
} else {
stream - > write_function ( stream , " -ERR No such profile \n " ) ;
goto done ;
2008-05-17 00:33:34 +00:00
}
2009-05-12 04:58:32 +00:00
} else {
/* Kept for backwards-compatibility */
switch_hash_index_t * hi ;
2009-04-25 14:16:32 +00:00
switch_mutex_lock ( globals . mutex ) ;
2009-06-20 03:29:43 +00:00
if ( ( hi = switch_hash_first ( NULL , globals . profile_hash ) ) ) {
2009-05-12 04:58:32 +00:00
void * val ;
2008-05-17 00:33:34 +00:00
switch_hash_this ( hi , NULL , NULL , & val ) ;
profile = ( vm_profile_t * ) val ;
2008-05-27 04:54:52 +00:00
total_new_messages = total_saved_messages = 0 ;
2008-05-17 00:33:34 +00:00
message_count ( profile , id , domain , " inbox " , & total_new_messages , & total_saved_messages ,
& total_new_urgent_messages , & total_saved_urgent_messages ) ;
}
2009-04-25 14:16:32 +00:00
switch_mutex_unlock ( globals . mutex ) ;
2008-05-17 00:33:34 +00:00
}
}
if ( ! strcasecmp ( how , " saved " ) ) {
stream - > write_function ( stream , " %d " , total_saved_messages ) ;
} else if ( ! strcasecmp ( how , " new-urgent " ) ) {
stream - > write_function ( stream , " %d " , total_new_urgent_messages ) ;
} else if ( ! strcasecmp ( how , " new-saved " ) ) {
stream - > write_function ( stream , " %d " , total_saved_urgent_messages ) ;
} else if ( ! strcasecmp ( how , " all " ) ) {
stream - > write_function ( stream , " %d:%d:%d:%d " , total_new_messages , total_saved_messages , total_new_urgent_messages , total_saved_urgent_messages ) ;
} else {
stream - > write_function ( stream , " %d " , total_new_messages ) ;
}
2010-02-06 03:38:24 +00:00
done :
2009-05-12 04:58:32 +00:00
switch_safe_free ( dup ) ;
2008-05-17 00:33:34 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2010-02-06 03:38:24 +00:00
2009-09-25 19:32:44 +00:00
# define PREFS_SYNTAX "[profile / ]<user>@<domain>[|[name_path|greeting_path|password]]"
SWITCH_STANDARD_API ( prefs_api_function )
{
2009-09-25 19:53:30 +00:00
char * dup = NULL ;
const char * how = " greeting_path " ;
vm_profile_t * profile = NULL ;
char * id , * domain , * p , * profilename = NULL ;
char sql [ 256 ] ;
2010-02-06 03:38:24 +00:00
prefs_callback_t cbt = { { 0 } } ;
2009-09-25 19:53:30 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( cmd ) ) {
2009-09-25 19:53:30 +00:00
stream - > write_function ( stream , " %d " , 0 ) ;
goto done ;
}
id = dup = strdup ( cmd ) ;
if ( ( p = strchr ( dup , ' / ' ) ) ) {
* p + + = ' \0 ' ;
id = p ;
profilename = dup ;
}
if ( ! strncasecmp ( id , " sip: " , 4 ) ) {
id + = 4 ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( id ) ) {
2009-09-25 19:53:30 +00:00
stream - > write_function ( stream , " %d " , 0 ) ;
goto done ;
}
if ( ( domain = strchr ( id , ' @ ' ) ) ) {
* domain + + = ' \0 ' ;
if ( ( p = strchr ( domain , ' | ' ) ) ) {
* p + + = ' \0 ' ;
how = p ;
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( profilename ) & & ! ( profile = get_profile ( profilename ) ) ) {
2009-09-25 19:53:30 +00:00
stream - > write_function ( stream , " -ERR No such profile \n " ) ;
goto done ;
}
if ( ! ( profile = get_profile ( " default " ) ) ) {
stream - > write_function ( stream , " -ERR profile 'default' doesn't exist \n " ) ;
goto done ;
}
} else {
stream - > write_function ( stream , " -ERR No domain specified \n " ) ;
goto done ;
}
switch_snprintf ( sql , sizeof ( sql ) , " select * from voicemail_prefs where username='%s' and domain='%s' " , id , domain ) ;
vm_execute_sql_callback ( profile , profile - > mutex , sql , prefs_callback , & cbt ) ;
if ( ! strcasecmp ( how , " greeting_path " ) ) {
stream - > write_function ( stream , " %s " , cbt . greeting_path ) ;
} else if ( ! strcasecmp ( how , " name_path " ) ) {
stream - > write_function ( stream , " %s " , cbt . name_path ) ;
} else if ( ! strcasecmp ( how , " password " ) ) {
stream - > write_function ( stream , " %s " , cbt . password ) ;
} else {
stream - > write_function ( stream , " %s:%s:%s " , cbt . greeting_path , cbt . name_path , cbt . password ) ;
2010-02-06 03:38:24 +00:00
}
2009-09-25 19:53:30 +00:00
profile_rwunlock ( profile ) ;
2010-02-06 03:38:24 +00:00
done :
2009-09-25 19:53:30 +00:00
switch_safe_free ( dup ) ;
return SWITCH_STATUS_SUCCESS ;
2009-09-25 19:32:44 +00:00
}
2008-05-17 00:33:34 +00:00
2009-04-24 14:27:19 +00:00
# define parse_profile() {\
total_new_messages = total_saved_messages = 0 ; \
message_count ( profile , id , domain , " inbox " , & total_new_messages , & total_saved_messages , \
& total_new_urgent_messages , & total_saved_urgent_messages ) ; \
2009-04-25 14:16:32 +00:00
if ( total_new_messages | | total_saved_messages ) { \
2009-04-24 14:27:19 +00:00
if ( switch_event_create ( & new_event , SWITCH_EVENT_MESSAGE_WAITING ) = = SWITCH_STATUS_SUCCESS ) { \
const char * yn = " no " ; \
if ( total_new_messages | | total_new_urgent_messages ) { \
yn = " yes " ; \
} \
2009-04-25 14:16:32 +00:00
switch_event_add_header_string ( new_event , SWITCH_STACK_BOTTOM , " MWI-Messages-Waiting " , yn ) ; \
2009-04-24 14:27:19 +00:00
switch_event_add_header_string ( new_event , SWITCH_STACK_BOTTOM , " MWI-Message-Account " , account ) ; \
switch_event_add_header ( new_event , SWITCH_STACK_BOTTOM , " MWI-Voice-Message " , " %d/%d (%d/%d) " , \
2009-04-25 14:16:32 +00:00
+ total_new_messages , total_saved_messages , total_new_urgent_messages , total_saved_urgent_messages ) ; \
2009-04-24 14:27:19 +00:00
created + + ; \
} \
} \
}
2008-05-17 00:33:34 +00:00
static void message_query_handler ( switch_event_t * event )
2007-10-12 22:08:30 +00:00
{
char * account = switch_event_get_header ( event , " message-account " ) ;
2008-05-08 16:09:49 +00:00
int created = 0 ;
2007-12-26 17:37:13 +00:00
switch_event_t * new_event = NULL ;
2008-05-17 00:33:34 +00:00
char * dup = NULL ;
2009-04-24 14:27:19 +00:00
int total_new_messages = 0 ;
int total_saved_messages = 0 ;
int total_new_urgent_messages = 0 ;
int total_saved_urgent_messages = 0 ;
2007-10-12 22:08:30 +00:00
if ( account ) {
2007-12-26 17:37:13 +00:00
switch_hash_index_t * hi ;
void * val ;
vm_profile_t * profile ;
char * id , * domain ;
2008-05-17 00:33:34 +00:00
dup = strdup ( account ) ;
id = dup ;
2007-12-26 17:37:13 +00:00
if ( ! strncasecmp ( account , " sip: " , 4 ) ) {
2008-05-17 15:48:18 +00:00
id + = 4 ;
2008-05-17 00:33:34 +00:00
}
2009-04-25 14:16:32 +00:00
2008-05-17 00:33:34 +00:00
if ( ! id ) {
free ( dup ) ;
return ;
2007-12-26 17:37:13 +00:00
}
if ( ( domain = strchr ( id , ' @ ' ) ) ) {
* domain + + = ' \0 ' ;
2009-04-24 14:27:19 +00:00
profile = NULL ;
if ( globals . message_query_exact_match ) {
if ( ( profile = ( vm_profile_t * ) switch_core_hash_find ( globals . profile_hash , domain ) ) ) {
parse_profile ( ) ;
}
} else {
for ( hi = switch_hash_first ( NULL , globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , NULL , NULL , & val ) ;
profile = ( vm_profile_t * ) val ;
parse_profile ( ) ;
2007-12-26 17:37:13 +00:00
}
}
}
2009-04-25 14:16:32 +00:00
2008-05-17 00:33:34 +00:00
switch_safe_free ( dup ) ;
2009-04-25 14:16:32 +00:00
2007-12-26 17:37:13 +00:00
}
2008-05-08 16:09:49 +00:00
if ( ! created ) {
2007-12-26 17:37:13 +00:00
if ( switch_event_create ( & new_event , SWITCH_EVENT_MESSAGE_WAITING ) = = SWITCH_STATUS_SUCCESS ) {
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( new_event , SWITCH_STACK_BOTTOM , " MWI-Messages-Waiting " , " no " ) ;
switch_event_add_header_string ( new_event , SWITCH_STACK_BOTTOM , " MWI-Message-Account " , account ) ;
2007-12-26 17:37:13 +00:00
}
}
2008-05-08 16:09:49 +00:00
if ( new_event ) {
switch_event_header_t * hp ;
for ( hp = event - > headers ; hp ; hp = hp - > next ) {
if ( ! strncasecmp ( hp - > name , " vm- " , 3 ) ) {
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( new_event , SWITCH_STACK_BOTTOM , hp - > name + 3 , hp - > value ) ;
2008-05-08 16:09:49 +00:00
}
}
switch_event_fire ( & new_event ) ;
}
2007-10-12 22:08:30 +00:00
}
2007-11-28 19:56:25 +00:00
struct holder {
2007-12-26 17:37:13 +00:00
vm_profile_t * profile ;
switch_memory_pool_t * pool ;
2007-11-28 19:56:25 +00:00
switch_stream_handle_t * stream ;
switch_xml_t xml ;
2007-12-26 17:37:13 +00:00
switch_xml_t x_item ;
switch_xml_t x_channel ;
int items ;
2009-05-18 17:06:13 +00:00
const char * user ;
const char * domain ;
const char * host ;
const char * port ;
const char * uri ;
2007-11-28 19:56:25 +00:00
} ;
static int del_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
2007-12-26 17:37:13 +00:00
if ( argc > 8 ) {
2007-12-15 04:58:44 +00:00
if ( unlink ( argv [ 8 ] ) ! = 0 ) {
2008-10-11 06:19:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Failed to delete file [%s] \n " , argv [ 8 ] ) ;
2007-12-15 04:58:44 +00:00
}
2007-12-26 17:37:13 +00:00
}
return 0 ;
2007-11-28 19:56:25 +00:00
}
static int play_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
2007-12-26 17:37:13 +00:00
switch_file_t * fd ;
struct holder * holder = ( struct holder * ) pArg ;
char * fname , * ext ;
switch_size_t flen ;
uint8_t chunk [ 1024 ] ;
2007-11-28 19:56:25 +00:00
const char * mime_type = " audio/inline " , * new_type ;
2007-12-26 17:37:13 +00:00
if ( ( fname = strrchr ( argv [ 8 ] , ' / ' ) ) ) {
fname + + ;
} else {
fname = argv [ 8 ] ;
}
if ( ( ext = strrchr ( fname , ' . ' ) ) ) {
ext + + ;
if ( ( new_type = switch_core_mime_ext2type ( ext ) ) ) {
mime_type = new_type ;
}
}
if ( switch_file_open ( & fd , argv [ 8 ] , SWITCH_FOPEN_READ , SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE , holder - > pool ) = = SWITCH_STATUS_SUCCESS ) {
flen = switch_file_get_size ( fd ) ;
holder - > stream - > write_function ( holder - > stream , " Content-type: %s \n " , mime_type ) ;
2008-05-27 04:54:52 +00:00
holder - > stream - > write_function ( holder - > stream , " Content-length: %ld \n \n " , ( long ) flen ) ;
for ( ; ; ) {
2007-12-26 17:37:13 +00:00
switch_status_t status ;
flen = sizeof ( chunk ) ;
status = switch_file_read ( fd , chunk , & flen ) ;
if ( status ! = SWITCH_STATUS_SUCCESS | | flen = = 0 ) {
break ;
}
holder - > stream - > raw_write_function ( holder - > stream , chunk , flen ) ;
}
switch_file_close ( fd ) ;
}
return 0 ;
2007-11-28 19:56:25 +00:00
}
static void do_play ( vm_profile_t * profile , char * user , char * domain , char * file , switch_stream_handle_t * stream )
{
2007-12-26 17:37:13 +00:00
char * sql ;
struct holder holder ;
2008-05-27 04:54:52 +00:00
sql = switch_mprintf ( " update voicemail_msgs set read_epoch=%ld where username='%s' and domain='%s' and file_path like '%%%s' " ,
2009-01-25 21:23:07 +00:00
( long ) switch_epoch_time_now ( NULL ) , user , domain , file ) ;
2007-12-26 17:37:13 +00:00
vm_execute_sql ( profile , sql , profile - > mutex ) ;
free ( sql ) ;
2009-01-19 20:58:01 +00:00
sql = switch_mprintf ( " select * from voicemail_msgs where username='%s' and domain='%s' and file_path like '%%%s' order by created_epoch " ,
user , domain , file ) ;
2007-12-26 17:37:13 +00:00
memset ( & holder , 0 , sizeof ( holder ) ) ;
holder . profile = profile ;
holder . stream = stream ;
switch_core_new_memory_pool ( & holder . pool ) ;
vm_execute_sql_callback ( profile , profile - > mutex , sql , play_callback , & holder ) ;
switch_core_destroy_memory_pool ( & holder . pool ) ;
switch_safe_free ( sql ) ;
2007-11-28 19:56:25 +00:00
}
static void do_del ( vm_profile_t * profile , char * user , char * domain , char * file , switch_stream_handle_t * stream )
{
2008-08-28 05:28:05 +00:00
char * myfolder = " inbox " ;
2007-12-26 17:37:13 +00:00
char * sql ;
struct holder holder ;
char * ref = NULL ;
2008-05-24 03:46:19 +00:00
if ( stream - > param_event ) {
ref = switch_event_get_header ( stream - > param_event , " http-referer " ) ;
2007-12-26 17:37:13 +00:00
}
2009-01-19 20:58:01 +00:00
sql = switch_mprintf ( " select * from voicemail_msgs where username='%s' and domain='%s' and file_path like '%%%s' order by created_epoch " ,
user , domain , file ) ;
2007-12-26 17:37:13 +00:00
memset ( & holder , 0 , sizeof ( holder ) ) ;
holder . profile = profile ;
holder . stream = stream ;
vm_execute_sql_callback ( profile , profile - > mutex , sql , del_callback , & holder ) ;
switch_safe_free ( sql ) ;
2008-03-18 22:13:32 +00:00
sql = switch_mprintf ( " delete from voicemail_msgs where username='%s' and domain='%s' and file_path like '%%%s' " , user , domain , file ) ;
2007-12-26 17:37:13 +00:00
vm_execute_sql ( profile , sql , profile - > mutex ) ;
free ( sql ) ;
2008-08-28 05:28:05 +00:00
update_mwi ( profile , user , domain , myfolder ) ;
2007-12-26 17:37:13 +00:00
if ( ref ) {
2008-05-27 04:54:52 +00:00
stream - > write_function ( stream , " Content-type: text/html \n \n <h2>Message Deleted</h2> \n " " <META http-equiv= \" refresh \" content= \" 1;URL=%s \" > " , ref ) ;
}
2007-11-28 19:56:25 +00:00
}
2007-11-29 01:05:05 +00:00
static int web_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
2007-12-26 17:37:13 +00:00
struct holder * holder = ( struct holder * ) pArg ;
char * del , * get , * fname , * ext ;
switch_time_exp_t tm ;
2007-11-29 01:05:05 +00:00
char create_date [ 80 ] = " " ;
char read_date [ 80 ] = " " ;
char rss_date [ 80 ] = " " ;
switch_size_t retsize ;
2008-08-06 23:33:58 +00:00
switch_time_t l_created = 0 ;
switch_time_t l_read = 0 ;
2008-08-28 05:17:02 +00:00
switch_time_t l_duration = 0 ;
2007-12-26 17:37:13 +00:00
switch_core_time_duration_t duration ;
char duration_str [ 80 ] ;
const char * fmt = " %a, %e %b %Y %T %z " ;
char heard [ 80 ] ;
char title_b4 [ 128 ] = " " ;
2008-05-27 04:54:52 +00:00
char title_aft [ 128 * 3 ] = " " ;
2007-12-26 17:37:13 +00:00
if ( argc > 0 ) {
2010-02-06 03:38:24 +00:00
l_created = switch_time_make ( atol ( argv [ 0 ] ) , 0 ) ;
2007-12-26 17:37:13 +00:00
}
if ( argc > 1 ) {
2010-02-06 03:38:24 +00:00
l_read = switch_time_make ( atol ( argv [ 1 ] ) , 0 ) ;
2007-12-26 17:37:13 +00:00
}
if ( argc > 9 ) {
2010-02-06 03:38:24 +00:00
l_duration = switch_time_make ( atol ( argv [ 9 ] ) , 0 ) ;
2007-12-26 17:37:13 +00:00
}
2007-11-29 01:05:05 +00:00
2007-12-15 04:58:44 +00:00
if ( ( fname = strrchr ( argv [ 8 ] , ' / ' ) ) ) {
2007-12-26 17:37:13 +00:00
fname + + ;
} else {
fname = argv [ 8 ] ;
}
if ( ( ext = strrchr ( fname , ' . ' ) ) ) {
ext + + ;
}
2007-11-29 01:05:05 +00:00
switch_core_measure_time ( l_duration , & duration ) ;
2007-12-26 17:37:13 +00:00
duration . day + = duration . yr * 365 ;
duration . hr + = duration . day * 24 ;
2008-05-27 04:54:52 +00:00
switch_snprintf ( duration_str , sizeof ( duration_str ) , " %.2u:%.2u:%.2u " , duration . hr , duration . min , duration . sec ) ;
2007-12-26 17:37:13 +00:00
if ( l_created ) {
switch_time_exp_lt ( & tm , l_created ) ;
2008-10-12 21:51:51 +00:00
switch_strftime_nocheck ( create_date , & retsize , sizeof ( create_date ) , fmt , & tm ) ;
switch_strftime_nocheck ( rss_date , & retsize , sizeof ( create_date ) , " %D %T " , & tm ) ;
2007-12-26 17:37:13 +00:00
}
if ( l_read ) {
switch_time_exp_lt ( & tm , l_read ) ;
2008-10-12 21:51:51 +00:00
switch_strftime_nocheck ( read_date , & retsize , sizeof ( read_date ) , fmt , & tm ) ;
2007-12-26 17:37:13 +00:00
}
switch_snprintf ( heard , sizeof ( heard ) , * read_date = = ' \0 ' ? " never " : read_date ) ;
get = switch_mprintf ( " http://%s:%s%s/get/%s " , holder - > host , holder - > port , holder - > uri , fname ) ;
del = switch_mprintf ( " http://%s:%s%s/del/%s " , holder - > host , holder - > port , holder - > uri , fname ) ;
2008-05-27 04:54:52 +00:00
holder - > stream - > write_function ( holder - > stream , " <font face=tahoma><div class=title><b>Message from %s %s</b></div><hr noshade size=1> \n " ,
argv [ 5 ] , argv [ 6 ] ) ;
holder - > stream - > write_function ( holder - > stream , " Priority: %s<br> \n " " Created: %s<br> \n " " Last Heard: %s<br> \n " " Duration: %s<br> \n " ,
//"<a href=%s>Delete This Message</a><br><hr noshade size=1>",
strcmp ( argv [ 10 ] , URGENT_FLAG_STRING ) ? " normal " : " urgent " , create_date , heard , duration_str ) ;
2007-12-26 17:37:13 +00:00
switch_snprintf ( title_b4 , sizeof ( title_b4 ) , " %s <%s> %s " , argv [ 5 ] , argv [ 6 ] , rss_date ) ;
2008-05-21 21:31:17 +00:00
switch_url_encode ( title_b4 , title_aft , sizeof ( title_aft ) ) ;
2007-11-29 01:05:05 +00:00
2007-12-15 04:58:44 +00:00
holder - > stream - > write_function ( holder - > stream ,
2008-05-27 04:54:52 +00:00
" <br><object width=550 height=15 \n "
" type= \" application/x-shockwave-flash \" \n "
" data= \" http://%s:%s/pub/slim.swf?song_url=%s&player_title=%s \" > \n "
" <param name=movie value= \" http://%s:%s/pub/slim.swf?song_url=%s&player_title=%s \" ></object><br><br> \n "
" [<a href=%s>delete</a>] [<a href=%s>download</a>] [<a href=tel:%s>call</a>] <br><br><br></font> \n " ,
holder - > host , holder - > port , get , title_aft , holder - > host , holder - > port , get , title_aft , del , get , argv [ 6 ] ) ;
2007-11-29 01:05:05 +00:00
2007-12-26 17:37:13 +00:00
free ( get ) ;
free ( del ) ;
2007-11-29 01:05:05 +00:00
2007-12-26 17:37:13 +00:00
return 0 ;
2007-11-29 01:05:05 +00:00
}
2007-11-28 19:56:25 +00:00
static int rss_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
2007-12-26 17:37:13 +00:00
struct holder * holder = ( struct holder * ) pArg ;
switch_xml_t x_tmp , x_link ;
char * tmp , * del , * get ;
switch_time_exp_t tm ;
2007-11-28 19:56:25 +00:00
char create_date [ 80 ] = " " ;
char read_date [ 80 ] = " " ;
char rss_date [ 80 ] = " " ;
switch_size_t retsize ;
const char * mime_type = " audio/inline " , * new_type ;
2007-12-26 17:37:13 +00:00
char * ext ;
char * fname ;
switch_size_t flen ;
switch_file_t * fd ;
2008-08-06 23:33:58 +00:00
switch_time_t l_created = 0 ;
switch_time_t l_read = 0 ;
2008-08-28 05:17:02 +00:00
switch_time_t l_duration = 0 ;
2007-12-26 17:37:13 +00:00
switch_core_time_duration_t duration ;
char duration_str [ 80 ] ;
const char * fmt = " %a, %e %b %Y %T %z " ;
char heard [ 80 ] ;
if ( argc > 0 ) {
2010-02-06 03:38:24 +00:00
l_created = switch_time_make ( atol ( argv [ 0 ] ) , 0 ) ;
2007-12-26 17:37:13 +00:00
}
if ( argc > 1 ) {
2010-02-06 03:38:24 +00:00
l_read = switch_time_make ( atol ( argv [ 1 ] ) , 0 ) ;
2007-12-26 17:37:13 +00:00
}
if ( argc > 9 ) {
2010-02-06 03:38:24 +00:00
l_duration = switch_time_make ( atol ( argv [ 9 ] ) , 0 ) ;
2007-12-26 17:37:13 +00:00
}
2007-11-28 19:56:25 +00:00
switch_core_measure_time ( l_duration , & duration ) ;
2007-12-26 17:37:13 +00:00
duration . day + = duration . yr * 365 ;
duration . hr + = duration . day * 24 ;
2008-05-27 04:54:52 +00:00
switch_snprintf ( duration_str , sizeof ( duration_str ) , " %.2u:%.2u:%.2u " , duration . hr , duration . min , duration . sec ) ;
2007-12-26 17:37:13 +00:00
if ( l_created ) {
switch_time_exp_lt ( & tm , l_created ) ;
2008-10-12 21:51:51 +00:00
switch_strftime_nocheck ( create_date , & retsize , sizeof ( create_date ) , fmt , & tm ) ;
switch_strftime_nocheck ( rss_date , & retsize , sizeof ( create_date ) , fmt , & tm ) ;
2007-12-26 17:37:13 +00:00
}
if ( l_read ) {
switch_time_exp_lt ( & tm , l_read ) ;
2008-10-12 21:51:51 +00:00
switch_strftime_nocheck ( read_date , & retsize , sizeof ( read_date ) , fmt , & tm ) ;
2007-12-26 17:37:13 +00:00
}
holder - > x_item = switch_xml_add_child_d ( holder - > x_channel , " item " , holder - > items + + ) ;
x_tmp = switch_xml_add_child_d ( holder - > x_item , " title " , 0 ) ;
tmp = switch_mprintf ( " Message from %s %s on %s " , argv [ 5 ] , argv [ 6 ] , create_date ) ;
switch_xml_set_txt_d ( x_tmp , tmp ) ;
free ( tmp ) ;
x_tmp = switch_xml_add_child_d ( holder - > x_item , " description " , 0 ) ;
switch_snprintf ( heard , sizeof ( heard ) , * read_date = = ' \0 ' ? " never " : read_date ) ;
if ( ( fname = strrchr ( argv [ 8 ] , ' / ' ) ) ) {
fname + + ;
} else {
fname = argv [ 8 ] ;
}
get = switch_mprintf ( " http://%s:%s%s/get/%s " , holder - > host , holder - > port , holder - > uri , fname ) ;
del = switch_mprintf ( " http://%s:%s%s/del/%s " , holder - > host , holder - > port , holder - > uri , fname ) ;
x_link = switch_xml_add_child_d ( holder - > x_item , " fsvm:rmlink " , 0 ) ;
switch_xml_set_txt_d ( x_link , del ) ;
2007-11-28 19:56:25 +00:00
2007-12-15 04:58:44 +00:00
tmp = switch_mprintf ( " <![CDATA[Priority: %s<br> "
2008-05-27 04:54:52 +00:00
" Last Heard: %s<br>Duration: %s<br> "
" <a href=%s>Delete This Message</a><br> "
" ]]> " , strcmp ( argv [ 10 ] , URGENT_FLAG_STRING ) ? " normal " : " urgent " , heard , duration_str , del ) ;
2007-11-28 19:56:25 +00:00
2007-12-26 17:37:13 +00:00
switch_xml_set_txt_d ( x_tmp , tmp ) ;
free ( tmp ) ;
free ( del ) ;
2007-11-28 19:56:25 +00:00
2007-12-15 04:58:44 +00:00
x_tmp = switch_xml_add_child_d ( holder - > x_item , " pubDate " , 0 ) ;
2007-12-26 17:37:13 +00:00
switch_xml_set_txt_d ( x_tmp , rss_date ) ;
2007-11-28 19:56:25 +00:00
2007-12-26 17:37:13 +00:00
x_tmp = switch_xml_add_child_d ( holder - > x_item , " itunes:duration " , 0 ) ;
switch_xml_set_txt_d ( x_tmp , duration_str ) ;
2007-11-28 19:56:25 +00:00
2007-12-15 04:58:44 +00:00
x_tmp = switch_xml_add_child_d ( holder - > x_item , " guid " , 0 ) ;
2007-12-26 17:37:13 +00:00
switch_xml_set_txt_d ( x_tmp , get ) ;
2007-11-28 19:56:25 +00:00
2007-12-26 17:37:13 +00:00
x_link = switch_xml_add_child_d ( holder - > x_item , " link " , 0 ) ;
switch_xml_set_txt_d ( x_link , get ) ;
2007-11-28 19:56:25 +00:00
2007-12-26 17:37:13 +00:00
x_tmp = switch_xml_add_child_d ( holder - > x_item , " enclosure " , 0 ) ;
switch_xml_set_attr_d ( x_tmp , " url " , get ) ;
free ( get ) ;
2007-11-28 19:56:25 +00:00
2007-12-15 04:58:44 +00:00
if ( switch_file_open ( & fd , argv [ 8 ] , SWITCH_FOPEN_READ , SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE , holder - > pool ) = = SWITCH_STATUS_SUCCESS ) {
2007-12-26 17:37:13 +00:00
flen = switch_file_get_size ( fd ) ;
tmp = switch_mprintf ( " %ld " , ( long ) flen ) ;
switch_xml_set_attr_d ( x_tmp , " length " , tmp ) ;
free ( tmp ) ;
switch_file_close ( fd ) ;
}
if ( ( ext = strrchr ( fname , ' . ' ) ) ) {
ext + + ;
if ( ( new_type = switch_core_mime_ext2type ( ext ) ) ) {
mime_type = new_type ;
}
}
switch_xml_set_attr_d ( x_tmp , " type " , mime_type ) ;
return 0 ;
2007-11-28 19:56:25 +00:00
}
static void do_rss ( vm_profile_t * profile , char * user , char * domain , char * host , char * port , char * uri , switch_stream_handle_t * stream )
{
2007-12-26 17:37:13 +00:00
struct holder holder ;
switch_xml_t x_tmp ;
char * sql , * xmlstr ;
char * tmp = NULL ;
stream - > write_function ( stream , " Content-type: text/xml \n \n " ) ;
memset ( & holder , 0 , sizeof ( holder ) ) ;
holder . profile = profile ;
holder . stream = stream ;
holder . xml = switch_xml_new ( " rss " ) ;
holder . user = user ;
holder . domain = domain ;
holder . host = host ;
holder . port = port ;
holder . uri = uri ;
switch_core_new_memory_pool ( & holder . pool ) ;
switch_assert ( holder . xml ) ;
switch_xml_set_attr_d ( holder . xml , " xmlns:itunes " , " http://www.itunes.com/dtds/podcast-1.0.dtd " ) ;
switch_xml_set_attr_d ( holder . xml , " xmlns:fsvm " , " http://www.freeswitch.org/dtd/fsvm.dtd " ) ;
switch_xml_set_attr_d ( holder . xml , " version " , " 2.0 " ) ;
holder . x_channel = switch_xml_add_child_d ( holder . xml , " channel " , 0 ) ;
x_tmp = switch_xml_add_child_d ( holder . x_channel , " title " , 0 ) ;
tmp = switch_mprintf ( " FreeSWITCH Voicemail for %s@%s " , user , domain ) ;
switch_xml_set_txt_d ( x_tmp , tmp ) ;
free ( tmp ) ;
x_tmp = switch_xml_add_child_d ( holder . x_channel , " link " , 0 ) ;
switch_xml_set_txt_d ( x_tmp , " http://www.freeswitch.org " ) ;
x_tmp = switch_xml_add_child_d ( holder . x_channel , " description " , 0 ) ;
switch_xml_set_txt_d ( x_tmp , " http://www.freeswitch.org " ) ;
x_tmp = switch_xml_add_child_d ( holder . x_channel , " ttl " , 0 ) ;
switch_xml_set_txt_d ( x_tmp , " 15 " ) ;
2007-11-28 19:56:25 +00:00
2009-01-19 20:58:01 +00:00
sql = switch_mprintf ( " select * from voicemail_msgs where username='%s' and domain='%s' order by read_flags, created_epoch " , user , domain ) ;
2007-12-26 17:37:13 +00:00
vm_execute_sql_callback ( profile , profile - > mutex , sql , rss_callback , & holder ) ;
2007-11-28 19:56:25 +00:00
2007-12-26 17:37:13 +00:00
xmlstr = switch_xml_toxml ( holder . xml , SWITCH_TRUE ) ;
2007-11-28 19:56:25 +00:00
2007-12-26 17:37:13 +00:00
stream - > write_function ( stream , " %s " , xmlstr ) ;
2007-11-28 19:56:25 +00:00
2007-12-26 17:37:13 +00:00
switch_safe_free ( sql ) ;
switch_safe_free ( xmlstr ) ;
switch_xml_free ( holder . xml ) ;
switch_core_destroy_memory_pool ( & holder . pool ) ;
2007-11-28 19:56:25 +00:00
}
2007-11-29 01:05:05 +00:00
2010-02-06 03:38:24 +00:00
static void do_web ( vm_profile_t * profile , const char * user_in , const char * domain , const char * host , const char * port , const char * uri ,
switch_stream_handle_t * stream )
2007-11-29 01:05:05 +00:00
{
2007-12-26 17:37:13 +00:00
char buf [ 80 ] = " " ;
struct holder holder ;
char * sql ;
callback_t cbt = { 0 } ;
int ttl = 0 ;
2009-05-18 17:34:35 +00:00
char * user ;
2007-12-26 17:37:13 +00:00
2009-05-18 17:34:35 +00:00
user = resolve_id ( user_in , domain , " web-vm " ) ;
2009-05-18 17:06:13 +00:00
2007-12-26 17:37:13 +00:00
stream - > write_function ( stream , " Content-type: text/html \n \n " ) ;
memset ( & holder , 0 , sizeof ( holder ) ) ;
holder . profile = profile ;
holder . stream = stream ;
holder . user = user ;
holder . domain = domain ;
holder . host = host ;
holder . port = port ;
holder . uri = uri ;
2007-11-29 01:05:05 +00:00
2007-12-15 04:58:44 +00:00
if ( profile - > web_head ) {
2008-05-27 04:54:52 +00:00
stream - > raw_write_function ( stream , ( uint8_t * ) profile - > web_head , strlen ( profile - > web_head ) ) ;
2007-12-26 17:37:13 +00:00
}
cbt . buf = buf ;
cbt . len = sizeof ( buf ) ;
2009-01-19 20:58:01 +00:00
sql = switch_mprintf ( " select * from voicemail_msgs where username='%s' and domain='%s' order by read_flags, created_epoch " , user , domain ) ;
2007-12-26 17:37:13 +00:00
vm_execute_sql_callback ( profile , profile - > mutex , sql , web_callback , & holder ) ;
switch_safe_free ( sql ) ;
2008-03-18 22:13:32 +00:00
sql = switch_mprintf ( " select count(*) from voicemail_msgs where username='%s' and domain='%s' order by read_flags " , user , domain ) ;
2007-12-26 17:37:13 +00:00
vm_execute_sql_callback ( profile , profile - > mutex , sql , sql2str_callback , & cbt ) ;
switch_safe_free ( sql ) ;
ttl = atoi ( buf ) ;
stream - > write_function ( stream , " %d message%s<br> " , ttl , ttl = = 1 ? " " : " s " ) ;
if ( profile - > web_tail ) {
2008-05-27 04:54:52 +00:00
stream - > raw_write_function ( stream , ( uint8_t * ) profile - > web_tail , strlen ( profile - > web_tail ) ) ;
2007-12-26 17:37:13 +00:00
}
2009-05-18 17:34:35 +00:00
if ( user ! = user_in ) {
free ( user ) ;
}
2007-11-29 01:05:05 +00:00
}
2008-12-29 22:26:10 +00:00
# define VM_INJECT_USAGE "[group=]<box> <sound_file> [<cid_num>] [<cid_name>]"
2008-07-17 19:46:25 +00:00
SWITCH_STANDARD_API ( voicemail_inject_api_function )
{
2008-07-29 17:32:30 +00:00
if ( voicemail_inject ( cmd ) = = SWITCH_STATUS_SUCCESS ) {
stream - > write_function ( stream , " %s " , " +OK \n " ) ;
} else {
stream - > write_function ( stream , " Error: %s \n " , VM_INJECT_USAGE ) ;
}
2008-07-17 19:46:25 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2010-02-17 05:00:01 +00:00
static int api_del_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
unlink ( argv [ 2 ] ) ;
return 0 ;
}
# define VM_DELETE_USAGE "<id>@<domain>[ / profile] [<uuid>]"
SWITCH_STANDARD_API ( voicemail_delete_api_function )
{
char * sql ;
char * id = NULL , * domain = NULL , * uuid = NULL , * profile_name = " default " ;
char * p , * e = NULL ;
vm_profile_t * profile ;
if ( zstr ( cmd ) ) {
stream - > write_function ( stream , " Usage: %s \n " , VM_DELETE_USAGE ) ;
return SWITCH_STATUS_SUCCESS ;
}
id = strdup ( cmd ) ;
if ( ( p = strchr ( id , ' @ ' ) ) ) {
* p + + = ' \0 ' ;
domain = e = p ;
}
2010-03-16 18:28:33 +00:00
if ( domain & & ( p = strchr ( domain , ' / ' ) ) ) {
2010-02-17 05:00:01 +00:00
* p + + = ' \0 ' ;
profile_name = e = p ;
}
if ( e & & ( p = strchr ( e , ' ' ) ) ) {
* p + + = ' \0 ' ;
uuid = p ;
}
if ( id & & domain & & profile_name & & ( profile = get_profile ( profile_name ) ) ) {
if ( uuid ) {
sql = switch_mprintf ( " select username, domain, in_folder, file_path from voicemail_msgs where uuid='%q' " , uuid ) ;
} else {
sql = switch_mprintf ( " select username, domain, in_folder, file_path from voicemail_msgs where username='%q' and domain='%q' " , id , domain ) ;
}
vm_execute_sql_callback ( profile , profile - > mutex , sql , api_del_callback , profile ) ;
switch_safe_free ( sql ) ;
if ( uuid ) {
sql = switch_mprintf ( " delete from voicemail_msgs where uuid='%q' " , uuid ) ;
} else {
sql = switch_mprintf ( " delete from voicemail_msgs where username='%q' and domain='%q' " , id , domain ) ;
}
vm_execute_sql ( profile , sql , profile - > mutex ) ;
switch_safe_free ( sql ) ;
update_mwi ( profile , id , domain , " inbox " ) ;
stream - > write_function ( stream , " %s " , " +OK \n " ) ;
2010-03-18 21:31:31 +00:00
profile_rwunlock ( profile ) ;
2010-02-17 05:00:01 +00:00
} else {
stream - > write_function ( stream , " %s " , " -ERR can't find user or profile. \n " ) ;
}
switch_safe_free ( id ) ;
return SWITCH_STATUS_SUCCESS ;
}
2010-03-15 20:40:49 +00:00
2010-03-18 18:24:19 +00:00
# define VM_READ_USAGE "<id>@<domain>[ / profile] <read|unread> [<uuid>]"
2010-03-15 20:40:49 +00:00
SWITCH_STANDARD_API ( voicemail_read_api_function )
{
char * sql ;
char * id = NULL , * domain = NULL , * uuid = NULL , * profile_name = " default " ;
2010-03-18 18:24:19 +00:00
char * ru = NULL , * p , * e = NULL ;
2010-03-15 20:40:49 +00:00
vm_profile_t * profile ;
2010-03-18 18:24:19 +00:00
int mread = - 1 ;
2010-03-15 20:40:49 +00:00
if ( zstr ( cmd ) ) {
stream - > write_function ( stream , " Usage: %s \n " , VM_READ_USAGE ) ;
return SWITCH_STATUS_SUCCESS ;
}
id = strdup ( cmd ) ;
if ( ( p = strchr ( id , ' @ ' ) ) ) {
* p + + = ' \0 ' ;
domain = e = p ;
}
2010-03-16 18:28:33 +00:00
if ( domain & & ( p = strchr ( domain , ' / ' ) ) ) {
2010-03-15 20:40:49 +00:00
* p + + = ' \0 ' ;
profile_name = e = p ;
}
if ( e & & ( p = strchr ( e , ' ' ) ) ) {
* p + + = ' \0 ' ;
2010-03-18 18:24:19 +00:00
ru = e = p ;
if ( ! strcasecmp ( ru , " read " ) ) {
mread = 1 ;
} else if ( ! strcasecmp ( ru , " unread " ) ) {
mread = 0 ;
} else {
mread = - 1 ;
}
}
if ( mread > - 1 ) {
if ( e & & ( p = strchr ( e , ' ' ) ) ) {
* p + + = ' \0 ' ;
uuid = p ;
}
2010-03-15 20:40:49 +00:00
}
2010-03-18 18:24:19 +00:00
if ( mread > - 1 & & id & & domain & & profile_name & & ( profile = get_profile ( profile_name ) ) ) {
2010-03-15 20:40:49 +00:00
2010-03-18 18:24:19 +00:00
if ( mread ) {
if ( uuid ) {
sql = switch_mprintf ( " update voicemail_msgs set read_epoch=%ld,flags='save' where uuid='%q' " , ( long ) switch_epoch_time_now ( NULL ) , uuid ) ;
} else {
sql = switch_mprintf ( " update voicemail_msgs set read_epoch=%ld,flags='save' where domain='%q' " , ( long ) switch_epoch_time_now ( NULL ) , domain ) ;
}
} else {
if ( uuid ) {
sql = switch_mprintf ( " update voicemail_msgs set read_epoch=0,flags='' where uuid='%q' " , uuid ) ;
} else {
sql = switch_mprintf ( " update voicemail_msgs set read_epoch=0,flags='' where domain='%q' " , domain ) ;
}
2010-03-15 20:40:49 +00:00
}
vm_execute_sql ( profile , sql , profile - > mutex ) ;
switch_safe_free ( sql ) ;
update_mwi ( profile , id , domain , " inbox " ) ;
stream - > write_function ( stream , " %s " , " +OK \n " ) ;
2010-03-18 21:31:31 +00:00
profile_rwunlock ( profile ) ;
2010-03-15 20:40:49 +00:00
} else {
stream - > write_function ( stream , " %s " , " -ERR can't find user or profile. \n " ) ;
}
switch_safe_free ( id ) ;
return SWITCH_STATUS_SUCCESS ;
}
2010-02-17 05:00:01 +00:00
static int api_list_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
switch_stream_handle_t * stream = ( switch_stream_handle_t * ) pArg ;
2010-03-16 18:28:33 +00:00
if ( ! strcasecmp ( argv [ 9 ] , " xml " ) ) {
2010-02-17 05:00:01 +00:00
stream - > write_function ( stream , " <message> \n " ) ;
2010-03-16 18:28:33 +00:00
stream - > write_function ( stream , " <created_epoch>%s</created_epoch> \n " , argv [ 0 ] ) ;
stream - > write_function ( stream , " <read_epoch>%s</read_epoch> \n " , argv [ 1 ] ) ;
stream - > write_function ( stream , " <username>%s</username> \n " , argv [ 2 ] ) ;
stream - > write_function ( stream , " <domain>%s</domain> \n " , argv [ 3 ] ) ;
stream - > write_function ( stream , " <folder>%s</folder> \n " , argv [ 4 ] ) ;
stream - > write_function ( stream , " <path>%s</path> \n " , argv [ 5 ] ) ;
stream - > write_function ( stream , " <uuid>%s</uuid> \n " , argv [ 6 ] ) ;
stream - > write_function ( stream , " <cid-name>%s</cid-name> \n " , argv [ 7 ] ) ;
stream - > write_function ( stream , " <cid-number>%s</cid-number> \n " , argv [ 8 ] ) ;
2010-02-17 05:00:01 +00:00
stream - > write_function ( stream , " </message> \n " ) ;
} else {
2010-03-16 18:28:33 +00:00
stream - > write_function ( stream , " %s:%s:%s:%s:%s:%s:%s:%s:%s \n " , argv [ 0 ] , argv [ 1 ] , argv [ 2 ] , argv [ 3 ] , argv [ 4 ] , argv [ 5 ] , argv [ 6 ] , argv [ 7 ] , argv [ 8 ] ) ;
2010-02-17 05:00:01 +00:00
}
return 0 ;
}
# define VM_LIST_USAGE "<id>@<domain>[ / profile] [xml]"
SWITCH_STANDARD_API ( voicemail_list_api_function )
{
char * sql ;
char * id = NULL , * domain = NULL , * format = " text " , * profile_name = " default " ;
char * p , * e = NULL ;
vm_profile_t * profile ;
if ( zstr ( cmd ) ) {
2010-03-15 20:40:49 +00:00
stream - > write_function ( stream , " Usage: %s \n " , VM_LIST_USAGE ) ;
2010-02-17 05:00:01 +00:00
return SWITCH_STATUS_SUCCESS ;
}
id = strdup ( cmd ) ;
if ( ( p = strchr ( id , ' @ ' ) ) ) {
* p + + = ' \0 ' ;
domain = e = p ;
}
2010-03-16 18:28:33 +00:00
if ( domain & & ( p = strchr ( domain , ' / ' ) ) ) {
2010-02-17 05:00:01 +00:00
* p + + = ' \0 ' ;
profile_name = e = p ;
}
if ( e & & ( p = strchr ( e , ' ' ) ) ) {
* p + + = ' \0 ' ;
format = p ;
}
if ( id & & domain & & profile_name & & ( profile = get_profile ( profile_name ) ) ) {
2010-03-16 18:28:33 +00:00
sql = switch_mprintf ( " select created_epoch, read_epoch, username, domain, in_folder, file_path, uuid, cid_name, cid_number, "
2010-02-18 23:53:56 +00:00
" '%q' from voicemail_msgs where username='%q' and domain='%q' " ,
2010-02-17 05:00:01 +00:00
format , id , domain ) ;
if ( ! strcasecmp ( format , " xml " ) ) {
stream - > write_function ( stream , " <voicemail> \n " ) ;
}
vm_execute_sql_callback ( profile , profile - > mutex , sql , api_list_callback , stream ) ;
switch_safe_free ( sql ) ;
update_mwi ( profile , id , domain , " inbox " ) ;
if ( ! strcasecmp ( format , " xml " ) ) {
stream - > write_function ( stream , " </voicemail> \n " ) ;
}
2010-03-18 21:31:31 +00:00
profile_rwunlock ( profile ) ;
2010-02-17 05:00:01 +00:00
} else {
stream - > write_function ( stream , " %s " , " -ERR can't find user or profile. \n " ) ;
}
switch_safe_free ( id ) ;
return SWITCH_STATUS_SUCCESS ;
}
2009-04-25 14:16:32 +00:00
# define VOICEMAIL_SYNTAX "rss [<host> <port> <uri> <user> <domain>] | [load|unload|reload] <profile> [reloadxml]"
2007-11-28 19:56:25 +00:00
SWITCH_STANDARD_API ( voicemail_api_function )
{
2007-12-26 17:37:13 +00:00
int argc = 0 ;
char * mydata = NULL , * argv [ 6 ] ;
char * host = NULL , * port = NULL , * uri = NULL ;
char * user = NULL , * domain = NULL ;
int ct = 0 ;
vm_profile_t * profile = NULL ;
char * path_info = NULL ;
int rss = 0 , xarg = 0 ;
2009-04-25 14:16:32 +00:00
switch_hash_index_t * hi ;
void * val = NULL ;
switch_xml_t xml_root ;
const char * err ;
2007-12-26 17:37:13 +00:00
2007-11-30 22:56:01 +00:00
if ( session ) {
return SWITCH_STATUS_FALSE ;
}
2008-05-24 03:46:19 +00:00
if ( stream - > param_event ) {
host = switch_event_get_header ( stream - > param_event , " http-host " ) ;
port = switch_event_get_header ( stream - > param_event , " http-port " ) ;
uri = switch_event_get_header ( stream - > param_event , " http-uri " ) ;
user = switch_event_get_header ( stream - > param_event , " freeswitch-user " ) ;
domain = switch_event_get_header ( stream - > param_event , " freeswitch-domain " ) ;
path_info = switch_event_get_header ( stream - > param_event , " http-path-info " ) ;
2007-12-26 17:37:13 +00:00
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( cmd ) ) {
2007-12-26 17:37:13 +00:00
mydata = strdup ( cmd ) ;
switch_assert ( mydata ) ;
argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
}
if ( argc > 0 ) {
if ( ! strcasecmp ( argv [ 0 ] , " rss " ) ) {
rss + + ;
xarg + + ;
2009-04-25 14:16:32 +00:00
} else if ( argc > 1 & & ! strcasecmp ( argv [ 0 ] , " load " ) ) {
if ( argc > 2 & & ! strcasecmp ( argv [ 2 ] , " reloadxml " ) ) {
if ( ( xml_root = switch_xml_open_root ( 1 , & err ) ) ) {
switch_xml_free ( xml_root ) ;
}
stream - > write_function ( stream , " Reload XML [%s] \n " , err ) ;
}
if ( ( profile = get_profile ( argv [ 1 ] ) ) ) {
2009-06-20 19:55:30 +00:00
profile_rwunlock ( profile ) ;
2009-04-25 14:16:32 +00:00
}
stream - > write_function ( stream , " +OK load complete \n " ) ;
goto done ;
} else if ( argc > 1 & & ! strcasecmp ( argv [ 0 ] , " unload " ) ) {
2009-06-20 19:55:30 +00:00
destroy_profile ( argv [ 1 ] , SWITCH_FALSE ) ;
2009-04-25 14:16:32 +00:00
stream - > write_function ( stream , " +OK unload complete \n " ) ;
goto done ;
} else if ( argc > 1 & & ! strcasecmp ( argv [ 0 ] , " reload " ) ) {
2009-06-20 19:55:30 +00:00
destroy_profile ( argv [ 1 ] , SWITCH_FALSE ) ;
2009-04-25 14:16:32 +00:00
if ( argc > 2 & & ! strcasecmp ( argv [ 2 ] , " reloadxml " ) ) {
if ( ( xml_root = switch_xml_open_root ( 1 , & err ) ) ) {
switch_xml_free ( xml_root ) ;
}
stream - > write_function ( stream , " Reload XML [%s] \n " , err ) ;
}
if ( ( profile = get_profile ( argv [ 1 ] ) ) ) {
2009-06-20 19:55:30 +00:00
profile_rwunlock ( profile ) ;
2009-04-25 14:16:32 +00:00
}
stream - > write_function ( stream , " +OK reload complete \n " ) ;
goto done ;
2010-02-06 03:38:24 +00:00
2009-04-25 14:16:32 +00:00
} else if ( ! strcasecmp ( argv [ 0 ] , " status " ) ) {
stream - > write_function ( stream , " ============================ \n " ) ;
switch_mutex_lock ( globals . mutex ) ;
for ( hi = switch_hash_first ( NULL , globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , NULL , NULL , & val ) ;
profile = ( vm_profile_t * ) val ;
stream - > write_function ( stream , " Profile: %s \n " , profile - > name ) ;
}
switch_mutex_unlock ( globals . mutex ) ;
stream - > write_function ( stream , " ============================ \n " ) ;
goto done ;
2007-12-26 17:37:13 +00:00
}
}
if ( ! host ) {
if ( argc - rss < 5 ) {
goto error ;
}
host = argv [ xarg + + ] ;
port = argv [ xarg + + ] ;
uri = argv [ xarg + + ] ;
user = argv [ xarg + + ] ;
domain = argv [ xarg + + ] ;
}
if ( ! ( host & & port & & uri & & user & & domain ) ) {
goto error ;
}
2009-04-25 14:16:32 +00:00
if ( ! ( profile = get_profile ( domain ) ) ) {
profile = get_profile ( " default " ) ;
2007-12-26 17:37:13 +00:00
}
if ( ! profile ) {
2009-05-11 22:28:02 +00:00
switch_hash_index_t * index ;
void * value ;
2007-12-26 17:37:13 +00:00
2009-04-25 14:16:32 +00:00
switch_mutex_lock ( globals . mutex ) ;
2009-05-11 22:28:02 +00:00
for ( index = switch_hash_first ( NULL , globals . profile_hash ) ; index ; index = switch_hash_next ( index ) ) {
switch_hash_this ( index , NULL , NULL , & value ) ;
profile = ( vm_profile_t * ) value ;
2007-11-28 22:27:33 +00:00
if ( profile ) {
2009-04-25 14:16:32 +00:00
switch_thread_rwlock_rdlock ( profile - > rwlock ) ;
2007-12-26 17:37:13 +00:00
break ;
2007-11-28 22:27:33 +00:00
}
2007-12-26 17:37:13 +00:00
}
2009-04-25 14:16:32 +00:00
switch_mutex_unlock ( globals . mutex ) ;
2007-12-26 17:37:13 +00:00
}
if ( ! profile ) {
stream - > write_function ( stream , " Can't find profile. \n " ) ;
goto error ;
}
if ( path_info ) {
if ( ! strncasecmp ( path_info , " get/ " , 4 ) ) {
2008-05-27 04:54:52 +00:00
do_play ( profile , user , domain , path_info + 4 , stream ) ;
2007-12-26 17:37:13 +00:00
} else if ( ! strncasecmp ( path_info , " del/ " , 4 ) ) {
2008-05-27 04:54:52 +00:00
do_del ( profile , user , domain , path_info + 4 , stream ) ;
2007-12-26 17:37:13 +00:00
} else if ( ! strncasecmp ( path_info , " web " , 3 ) ) {
do_web ( profile , user , domain , host , port , uri , stream ) ;
}
}
if ( rss | | ( path_info & & ! strncasecmp ( path_info , " rss " , 3 ) ) ) {
do_rss ( profile , user , domain , host , port , uri , stream ) ;
}
2009-06-20 19:55:30 +00:00
profile_rwunlock ( profile ) ;
2007-12-26 17:37:13 +00:00
goto done ;
2008-05-27 04:54:52 +00:00
error :
2007-12-26 17:37:13 +00:00
if ( host ) {
if ( ! ct ) {
stream - > write_function ( stream , " Content-type: text/html \n \n <h2> " ) ;
}
}
stream - > write_function ( stream , " Error: %s \n " , VOICEMAIL_SYNTAX ) ;
2008-05-27 04:54:52 +00:00
done :
2007-12-26 17:37:13 +00:00
switch_safe_free ( mydata ) ;
return SWITCH_STATUS_SUCCESS ;
2007-11-28 19:56:25 +00:00
}
2007-10-12 03:28:59 +00:00
SWITCH_MODULE_LOAD_FUNCTION ( mod_voicemail_load )
{
switch_application_interface_t * app_interface ;
2007-12-26 17:37:13 +00:00
switch_api_interface_t * commands_api_interface ;
switch_status_t status ;
2007-10-12 03:28:59 +00:00
2008-10-29 17:28:12 +00:00
/* create/register custom event message type */
if ( switch_event_reserve_subclass ( VM_EVENT_MAINT ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't register subclass %s! \n " , VM_EVENT_MAINT ) ;
return SWITCH_STATUS_TERM ;
}
2009-04-25 14:16:32 +00:00
memset ( & globals , 0 , sizeof ( globals ) ) ;
globals . pool = pool ;
switch_core_hash_init ( & globals . profile_hash , globals . pool ) ;
switch_mutex_init ( & globals . mutex , SWITCH_MUTEX_NESTED , globals . pool ) ;
2007-12-26 17:37:13 +00:00
if ( ( status = load_config ( ) ) ! = SWITCH_STATUS_SUCCESS ) {
return status ;
}
2007-10-12 03:28:59 +00:00
/* connect my internal structure to the blank pointer passed to me */
* module_interface = switch_loadable_module_create_module_interface ( pool , modname ) ;
2007-10-12 22:08:30 +00:00
2008-06-18 18:42:21 +00:00
if ( switch_event_bind ( modname , SWITCH_EVENT_MESSAGE_QUERY , SWITCH_EVENT_SUBCLASS_ANY , message_query_handler , NULL )
2007-10-12 22:08:30 +00:00
! = SWITCH_STATUS_SUCCESS ) {
2008-05-27 04:54:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_GENERR ;
2007-10-12 22:08:30 +00:00
}
2007-11-28 19:56:25 +00:00
2008-10-19 23:58:43 +00:00
SWITCH_ADD_APP ( app_interface , " voicemail " , " Voicemail " , VM_DESC , voicemail_function , VM_USAGE , SAF_NONE ) ;
2007-11-28 19:56:25 +00:00
SWITCH_ADD_API ( commands_api_interface , " voicemail " , " voicemail " , voicemail_api_function , VOICEMAIL_SYNTAX ) ;
2008-07-29 17:32:30 +00:00
SWITCH_ADD_API ( commands_api_interface , " voicemail_inject " , " voicemail_inject " , voicemail_inject_api_function , VM_INJECT_USAGE ) ;
2010-02-17 05:00:01 +00:00
SWITCH_ADD_API ( commands_api_interface , " vm_inject " , " vm_inject " , voicemail_inject_api_function , VM_INJECT_USAGE ) ;
2008-05-17 00:33:34 +00:00
SWITCH_ADD_API ( commands_api_interface , " vm_boxcount " , " vm_boxcount " , boxcount_api_function , BOXCOUNT_SYNTAX ) ;
2009-09-25 19:32:44 +00:00
SWITCH_ADD_API ( commands_api_interface , " vm_prefs " , " vm_prefs " , prefs_api_function , PREFS_SYNTAX ) ;
2010-02-17 05:00:01 +00:00
SWITCH_ADD_API ( commands_api_interface , " vm_delete " , " vm_delete " , voicemail_delete_api_function , VM_DELETE_USAGE ) ;
2010-03-15 20:40:49 +00:00
SWITCH_ADD_API ( commands_api_interface , " vm_read " , " vm_read " , voicemail_read_api_function , VM_READ_USAGE ) ;
2010-02-17 05:00:01 +00:00
SWITCH_ADD_API ( commands_api_interface , " vm_list " , " vm_list " , voicemail_list_api_function , VM_LIST_USAGE ) ;
2009-04-25 14:16:32 +00:00
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_MODULE_SHUTDOWN_FUNCTION ( mod_voicemail_shutdown )
{
switch_hash_index_t * hi ;
vm_profile_t * profile ;
void * val = NULL ;
const void * key ;
switch_ssize_t keylen ;
switch_event_free_subclass ( VM_EVENT_MAINT ) ;
switch_event_unbind_callback ( message_query_handler ) ;
switch_mutex_lock ( globals . mutex ) ;
2010-02-06 03:38:24 +00:00
while ( ( hi = switch_hash_first ( NULL , globals . profile_hash ) ) ) {
2009-04-25 14:16:32 +00:00
switch_hash_this ( hi , & key , & keylen , & val ) ;
profile = ( vm_profile_t * ) val ;
2010-02-06 03:38:24 +00:00
2009-04-25 14:16:32 +00:00
switch_core_hash_delete ( globals . profile_hash , profile - > name ) ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Waiting for write lock (Profile %s) \n " , profile - > name ) ;
2009-04-25 14:16:32 +00:00
switch_thread_rwlock_wrlock ( profile - > rwlock ) ;
2010-02-06 03:38:24 +00:00
2009-04-25 14:16:32 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Destroying Profile %s \n " , profile - > name ) ;
2009-06-24 16:02:43 +00:00
2009-04-25 14:16:32 +00:00
switch_core_destroy_memory_pool ( & profile - > pool ) ;
profile = NULL ;
}
switch_mutex_unlock ( globals . mutex ) ;
return SWITCH_STATUS_SUCCESS ;
2007-10-12 03:28:59 +00:00
}
2009-04-25 14:16:32 +00:00
2007-10-12 03:28:59 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2008-02-03 22:14:57 +00:00
* indent - tabs - mode : t
2007-10-12 03:28:59 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
2009-09-14 22:03:37 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 :
2007-10-12 03:28:59 +00:00
*/