From 1df3896b34414e3d5bb986f1aa1ec79dc69b6ff1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 17 Jul 2008 19:46:25 +0000 Subject: [PATCH] nut n' honey git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9073 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_apr.h | 6 + src/include/switch_channel.h | 1 + .../mod_voicemail/mod_voicemail.c | 669 +++++++++++++----- src/switch_apr.c | 9 + src/switch_channel.c | 9 + src/switch_core.c | 3 + 6 files changed, 503 insertions(+), 194 deletions(-) diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h index c4c64ba683..4434bdf720 100644 --- a/src/include/switch_apr.h +++ b/src/include/switch_apr.h @@ -728,6 +728,12 @@ SWITCH_DECLARE(switch_status_t) switch_file_open(switch_file_t **newf, const cha SWITCH_DECLARE(switch_status_t) switch_file_seek(switch_file_t *thefile, switch_seek_where_t where, int64_t *offset); + +SWITCH_DECLARE(switch_status_t) switch_file_copy(const char *from_path, + const char *to_path, + switch_fileperms_t perms, + switch_memory_pool_t *pool); + /** * Close the specified file. * @param thefile The file descriptor to close. diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index 7348eb8ad3..9b197fc93b 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -223,6 +223,7 @@ SWITCH_DECLARE(const char *) switch_channel_get_variable_partner(switch_channel_ \return the value of the requested variable */ SWITCH_DECLARE(const char *) switch_channel_get_variable(switch_channel_t *channel, const char *varname); +SWITCH_DECLARE(switch_status_t) switch_channel_get_variables(switch_channel_t *channel, switch_event_t **event); /*! * Start iterating over the entries in the channel variable list. diff --git a/src/mod/applications/mod_voicemail/mod_voicemail.c b/src/mod/applications/mod_voicemail/mod_voicemail.c index 9f95c4a833..9e1649fb09 100644 --- a/src/mod/applications/mod_voicemail/mod_voicemail.c +++ b/src/mod/applications/mod_voicemail/mod_voicemail.c @@ -46,6 +46,7 @@ SWITCH_MODULE_DEFINITION(mod_voicemail, mod_voicemail_load, NULL, NULL); #define VM_MAX_GREETINGS 9 + static struct { switch_hash_t *profile_hash; int debug; @@ -933,6 +934,30 @@ typedef enum { } msg_type_t; +switch_status_t measure_file_len(const char *path, switch_size_t *message_len) +{ + + switch_file_handle_t fh = { 0 }; + uint32_t pos = 0; + switch_status_t status = SWITCH_STATUS_FALSE; + + if (switch_core_file_open(&fh, + path, + 0, + 0, + SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) { + + if (switch_core_file_seek(&fh, &pos, 0, SEEK_END) == SWITCH_STATUS_SUCCESS) { + *message_len = pos; + status = SWITCH_STATUS_SUCCESS; + } + switch_core_file_close(&fh); + } + + return status; + +} + static switch_status_t create_file(switch_core_session_t *session, vm_profile_t *profile, char *macro_name, char *file_path, switch_size_t *message_len, switch_bool_t limit) { @@ -1727,10 +1752,432 @@ static void voicemail_check_main(switch_core_session_t *session, const char *pro } } + +static void deliver_vm(vm_profile_t *profile, + switch_xml_t x_user, + const char *domain_name, + const char *path, + uint32_t message_len, + const char *read_flags, + switch_event_t *params, + switch_memory_pool_t *pool, + const char *caller_id_name, + const char *caller_id_number, + switch_bool_t copy) +{ + 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; + int send_mail = 0; + int send_main = 0; + int send_notify = 0; + int insert_db = 1; + int email_attach = 0; + char *myfolder = "inbox"; + int priority = 3; + const char *tmp; + switch_event_t *local_event = NULL; + + if (params) { + switch_event_create(&local_event, SWITCH_EVENT_MESSAGE); + params = local_event; + } + + 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; + } + + switch_uuid_get(&uuid); + switch_uuid_format(uuid_str, &uuid); + + if ((filename = strrchr(path, *SWITCH_PATH_SEPARATOR))) { + filename++; + } else { + filename = path; + } + + if (!(x_params = switch_xml_child(x_user, "params"))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find params for user [%s@%s]\n", myid, domain_name); + goto failed; + } + + 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); + } else if (!strcasecmp(var, "vm-email-all-messages")) { + send_main = send_mail = switch_true(val); + } else if (!strcasecmp(var, "vm-notify-email-all-messages")) { + send_notify = send_mail = switch_true(val); + } 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); + } + } + + + if (switch_strlen_zero(profile->storage_dir)) { + 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); + } else { + dir_path = switch_mprintf("%s%s%s", profile->storage_dir, 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); + 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 { + file_path = (char *)path; + } + + 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; + switch_event_t *event; + char *mwi_id = NULL; + int total_new_messages = 0; + int total_saved_messages = 0; + int total_new_urgent_messages = 0; + int total_saved_urgent_messages = 0; + + usql = switch_mprintf("insert into voicemail_msgs values(%ld,0,'%q','%q','%q','%q','%q','%q','%q','%u','','%q')", (long) switch_timestamp(NULL), + myid, domain_name, uuid_str, caller_id_name, caller_id_number, + myfolder, file_path, message_len, read_flags); + vm_execute_sql(profile, usql, profile->mutex); + switch_safe_free(usql); + + message_count(profile, myid, domain_name, myfolder, &total_new_messages, &total_saved_messages, + &total_new_urgent_messages, &total_saved_urgent_messages); + + if (switch_event_create(&event, SWITCH_EVENT_MESSAGE_WAITING) == SWITCH_STATUS_SUCCESS) { + const char *yn = "no"; + if (total_new_messages || total_new_urgent_messages) { + yn = "yes"; + } + mwi_id = switch_mprintf("%s@%s", myid, domain_name); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", "%s", yn); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Message-Account", mwi_id); + 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); + switch_event_fire(&event); + switch_safe_free(mwi_id); + } + } + + if (send_mail && !switch_strlen_zero(vm_email) && switch_file_exists(file_path, pool) == SWITCH_STATUS_SUCCESS) { + switch_event_t *event; + char *from; + char *body; + char *headers; + char *header_string; + char tmp[50] = ""; + int total_new_messages = 0; + int total_saved_messages = 0; + int total_new_urgent_messages = 0; + int total_saved_urgent_messages = 0; + char *p; + long l_duration = 0; + 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); + + switch_time_exp_lt(&tm, switch_timestamp_now()); + switch_strftime(date, &retsize, sizeof(date), profile->date_fmt, &tm); + + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "voicemail_current_folder", myfolder); + switch_snprintf(tmp, sizeof(tmp), "%d", total_new_messages); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "voicemail_total_new_messages", tmp); + switch_snprintf(tmp, sizeof(tmp), "%d", total_saved_messages); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "voicemail_total_saved_messages", tmp); + switch_snprintf(tmp, sizeof(tmp), "%d", total_new_urgent_messages); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "voicemail_urgent_new_messages", tmp); + switch_snprintf(tmp, sizeof(tmp), "%d", total_saved_urgent_messages); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "voicemail_urgent_saved_messages", tmp); + 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); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "voicemail_time", date); + switch_snprintf(tmp, sizeof(tmp), "%d", priority); + switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "voicemail_priority", tmp); + 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); + } + l_duration = (long) message_len *1000000; + 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); + + if (switch_strlen_zero(profile->email_from)) { + from = switch_core_sprintf(pool, "%s@%s", myid, domain_name); + } else { + from = switch_event_expand_headers(params, profile->email_headers); + } + + + if (send_main) { + if (switch_strlen_zero(profile->email_headers)) { + headers = switch_mprintf( + "From: FreeSWITCH mod_voicemail <%s@%s>\n" + "Subject: Voicemail from %s %s\nX-Priority: %d", + myid, domain_name, caller_id_name, caller_id_number, priority); + } 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\nX-Voicemail-Length: %u", headers, message_len); + + switch_event_dup(&event, params); + + if (event) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Message-Type", "voicemail"); + 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) { + switch_simple_email(vm_email, from, header_string, body, file_path); + } else { + switch_simple_email(vm_email, from, header_string, body, NULL); + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending message to %s\n", vm_email); + switch_safe_free(body); + + if (headers != profile->email_headers) { + switch_safe_free(headers); + } + } + + + if (send_notify) { + if (switch_strlen_zero(profile->notify_email_headers)) { + headers = switch_mprintf( + "From: FreeSWITCH mod_voicemail <%s@%s>\n" + "Subject: Voicemail from %s %s\nX-Priority: %d", + myid, domain_name, caller_id_name, caller_id_number, priority); + } 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\nX-Voicemail-Length: %u", headers, message_len); + + switch_event_dup(&event, params); + + if (event) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Message-Type", "voicemail-notify"); + 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); + } + + switch_simple_email(vm_notify_email, from, header_string, body, NULL); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending notify message to %s\n", vm_notify_email); + switch_safe_free(body); + + if (headers != profile->notify_email_headers) { + switch_safe_free(headers); + } + } + + if (!insert_db) { + if (unlink(file_path) != 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "failed to delete file [%s]\n", file_path); + } + } + } + + failed: + + switch_event_destroy(&local_event); + + switch_safe_free(dir_path); + + if (file_path != path) { + switch_safe_free(file_path); + } + + return; + +} + +static switch_status_t voicemail_inject(const char *data) +{ + vm_profile_t *profile; + char *dup, *user = NULL, *domain = NULL; + switch_status_t status = SWITCH_STATUS_FALSE; + int istag = 0, isall = 0; + int argc = 0; + char *argv[4]; + char *box, *path, *cid_num, *cid_name; + switch_memory_pool_t *pool = NULL; + + dup = strdup(data); + switch_assert(dup); + + if ((argc = switch_separate_string(dup, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) < 2) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "not enough args [%s]\n", data); + goto end; + } + + box = argv[0]; + path = argv[1]; + cid_num = argv[2] ? argv[2] : "anonymous"; + cid_name = argv[3] ? argv[3] : "anonymous"; + + user = box; + + if ((domain = strchr(user, '@'))) { + *domain++ = '\0'; + } else { + domain = user; + } + + if (switch_stristr("tag=", user)) { + user += 3; + istag++; + } else if (user == domain) { + isall++; + } + + if (!(user && domain)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "invalid syntax [%s][%s]\n", switch_str_nil(user), switch_str_nil(domain)); + goto end; + } + + if (!(profile = switch_core_hash_find(globals.profile_hash, domain))) { + profile = switch_core_hash_find(globals.profile_hash, "default"); + } + + if (!profile) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find profile\n"); + } else { + switch_xml_t x_domain, xml_root; + switch_event_t *my_params = NULL; + switch_xml_t ut; + + switch_event_create(&my_params, SWITCH_EVENT_MESSAGE); + switch_assert(my_params); + 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"); + + 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); + switch_event_destroy(&my_params); + goto end; + } + + switch_event_destroy(&my_params); + + switch_core_new_memory_pool(&pool); + + if (!isall && !istag) { + ut = switch_xml_find_child(x_domain, "user", "id", user); + switch_event_create(&my_params, SWITCH_EVENT_MESSAGE); + deliver_vm(profile, ut, domain, path, 0, "B", my_params, pool, cid_name, cid_num, SWITCH_TRUE); + switch_event_destroy(&my_params); + } else { + for (ut = switch_xml_child(x_domain, "user"); ut; ut = ut->next) { + const char *tag; + + if (isall || (istag && (tag=switch_xml_attr(ut, "vm-tag")) && !strcasecmp(tag, user))) { + switch_event_create(&my_params, SWITCH_EVENT_MESSAGE); + deliver_vm(profile, ut, domain, path, 0, "B", my_params, pool, cid_name, cid_num, SWITCH_TRUE); + switch_event_destroy(&my_params); + } + } + } + + switch_core_destroy_memory_pool(&pool); + + switch_xml_free(xml_root); + + } + + + end: + + switch_safe_free(dup); + + return status; + +} + static switch_status_t voicemail_leave_main(switch_core_session_t *session, const char *profile_name, const char *domain_name, const char *id) { switch_channel_t *channel = switch_core_session_get_channel(session); - char *myfolder = "inbox"; char sql[256]; prefs_callback_t cbt; vm_profile_t *profile; @@ -1762,7 +2209,9 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, cons int insert_db = 1; const char *caller_id_name = NULL; const char *caller_id_number = NULL; - + switch_xml_t x_domain = NULL, x_domain_root = NULL, x_user = NULL, x_params = NULL, x_param = NULL; + switch_event_t *vars = NULL; + const char *vm_cc = NULL; if (!(caller_id_name = switch_channel_get_variable(channel, "effective_caller_id_name"))) { caller_id_name = caller_profile->caller_id_name; @@ -1794,14 +2243,12 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, cons if (id) { int ok = 1; switch_event_t *params = NULL; - switch_xml_t x_domain, x_domain_root, x_user, x_params, x_param; const char *email_addr = NULL; switch_event_create(¶ms, SWITCH_EVENT_MESSAGE); switch_assert(params); switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "mailbox", id); - x_user = x_domain = x_domain_root = NULL; if (switch_xml_locate_user("id", id, domain_name, switch_channel_get_variable(channel, "network_addr"), &x_domain_root, &x_domain, &x_user, params) == SWITCH_STATUS_SUCCESS) { if ((x_params = switch_xml_child(x_user, "params"))) { @@ -1859,7 +2306,7 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, cons } switch_event_destroy(¶ms); - switch_xml_free(x_domain_root); + if (!ok) { goto end; } @@ -1971,199 +2418,22 @@ static switch_status_t voicemail_leave_main(switch_core_session_t *session, cons TRY_CODE(switch_ivr_phrase_macro(session, VM_ACK_MACRO, "saved", NULL, NULL)); } } + + switch_channel_get_variables(channel, &vars); + deliver_vm(profile, x_user, domain_name, file_path, message_len, read_flags, vars, + switch_core_session_get_pool(session), caller_id_name, caller_id_number, SWITCH_FALSE); + switch_event_destroy(&vars); - if (insert_db && switch_file_exists(file_path, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { - char *usql; - switch_event_t *event; - char *mwi_id = NULL; - int total_new_messages = 0; - int total_saved_messages = 0; - int total_new_urgent_messages = 0; - int total_saved_urgent_messages = 0; - - usql = switch_mprintf("insert into voicemail_msgs values(%ld,0,'%q','%q','%q','%q','%q','%q','%q','%u','','%q')", (long) switch_timestamp(NULL), - id, domain_name, uuid, caller_id_name, caller_id_number, - myfolder, file_path, message_len, read_flags); - vm_execute_sql(profile, usql, profile->mutex); - switch_safe_free(usql); - - message_count(profile, id, domain_name, myfolder, &total_new_messages, &total_saved_messages, - &total_new_urgent_messages, &total_saved_urgent_messages); - - if (switch_event_create(&event, SWITCH_EVENT_MESSAGE_WAITING) == SWITCH_STATUS_SUCCESS) { - const char *yn = "no"; - if (total_new_messages || total_new_urgent_messages) { - yn = "yes"; - } - mwi_id = switch_mprintf("%s@%s", id, domain_name); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", "%s", yn); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "MWI-Message-Account", mwi_id); - 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); - switch_event_fire(&event); - switch_safe_free(mwi_id); - } + if ((vm_cc = switch_channel_get_variable(channel, "vm_cc"))) { + char *cmd = switch_core_session_sprintf(session, "%s %s %s %s", vm_cc, file_path, caller_id_number, caller_id_name); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Sent Carbon Copy to %s\n", vm_cc); + voicemail_inject(cmd); } - end: + end: - if (send_mail && !switch_strlen_zero(vm_email) && switch_file_exists(file_path, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { - switch_event_t *event; - char *from; - char *body; - char *headers; - char *header_string; - char tmp[50] = ""; - int total_new_messages = 0; - int total_saved_messages = 0; - int total_new_urgent_messages = 0; - int total_saved_urgent_messages = 0; - char *p; - long l_duration = 0; - switch_core_time_duration_t duration; - char duration_str[80]; - - message_count(profile, id, domain_name, myfolder, &total_new_messages, &total_saved_messages, - &total_new_urgent_messages, &total_saved_urgent_messages); - - switch_time_exp_lt(&tm, switch_timestamp_now()); - switch_strftime(date, &retsize, sizeof(date), profile->date_fmt, &tm); - - switch_channel_set_variable(channel, "voicemail_current_folder", myfolder); - switch_snprintf(tmp, sizeof(tmp), "%d", total_new_messages); - switch_channel_set_variable(channel, "voicemail_total_new_messages", tmp); - switch_snprintf(tmp, sizeof(tmp), "%d", total_saved_messages); - switch_channel_set_variable(channel, "voicemail_total_saved_messages", tmp); - switch_snprintf(tmp, sizeof(tmp), "%d", total_new_urgent_messages); - switch_channel_set_variable(channel, "voicemail_urgent_new_messages", tmp); - switch_snprintf(tmp, sizeof(tmp), "%d", total_saved_urgent_messages); - switch_channel_set_variable(channel, "voicemail_urgent_saved_messages", tmp); - switch_channel_set_variable(channel, "voicemail_account", id); - switch_channel_set_variable(channel, "voicemail_domain", domain_name); - switch_channel_set_variable(channel, "voicemail_caller_id_number", caller_id_number); - switch_channel_set_variable(channel, "voicemail_caller_id_name", caller_id_name); - switch_channel_set_variable(channel, "voicemail_file_path", file_path); - switch_channel_set_variable(channel, "voicemail_read_flags", read_flags); - switch_channel_set_variable(channel, "voicemail_time", date); - switch_snprintf(tmp, sizeof(tmp), "%d", priority); - switch_channel_set_variable(channel, "voicemail_priority", tmp); - if (vm_email) { - switch_channel_set_variable(channel, "voicemail_email", vm_email); - } - if (vm_notify_email) { - switch_channel_set_variable(channel, "voicemail_notify_email", vm_notify_email); - } - l_duration = (long) message_len *1000000; - 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_channel_set_variable(channel, "voicemail_message_len", duration_str); - - if (switch_strlen_zero(profile->email_from)) { - from = switch_core_session_sprintf(session, "%s@%s", id, domain_name); - } else { - from = switch_channel_expand_variables(channel, profile->email_headers); - } - - - if (send_main) { - if (switch_strlen_zero(profile->email_headers)) { - headers = switch_mprintf( - "From: FreeSWITCH mod_voicemail <%s@%s>\n" - "Subject: Voicemail from %s %s\nX-Priority: %d", - id, domain_name, caller_id_name, caller_id_number, priority); - } else { - headers = switch_channel_expand_variables(channel, profile->email_headers); - } - - p = headers + (strlen(headers) - 1); - - if (*p == '\n') { - if (*(p - 1) == '\r') { - p--; - } - *p = '\0'; - } - - header_string = switch_core_session_sprintf(session, "%s\nX-Voicemail-Length: %u", headers, message_len); - - if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Message-Type", "voicemail"); - switch_event_fire(&event); - } - - if (profile->email_body) { - body = switch_channel_expand_variables(channel, profile->email_body); - } else { - body = switch_mprintf("%u second Voicemail from %s %s", message_len, caller_id_name, caller_id_number); - } - - if (email_attach) { - switch_simple_email(vm_email, from, header_string, body, file_path); - } else { - switch_simple_email(vm_email, from, header_string, body, NULL); - } - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending message to %s\n", vm_email); - switch_safe_free(body); - - if (headers != profile->email_headers) { - switch_safe_free(headers); - } - } - - - if (send_notify) { - if (switch_strlen_zero(profile->notify_email_headers)) { - headers = switch_mprintf( - "From: FreeSWITCH mod_voicemail <%s@%s>\n" - "Subject: Voicemail from %s %s\nX-Priority: %d", - id, domain_name, caller_id_name, caller_id_number, priority); - } else { - headers = switch_channel_expand_variables(channel, profile->notify_email_headers); - } - - p = headers + (strlen(headers) - 1); - - if (*p == '\n') { - if (*(p - 1) == '\r') { - p--; - } - *p = '\0'; - } - - header_string = switch_core_session_sprintf(session, "%s\nX-Voicemail-Length: %u", headers, message_len); - - if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) { - switch_channel_event_set_data(channel, event); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Message-Type", "voicemail-notify"); - switch_event_fire(&event); - } - - if (profile->notify_email_body) { - body = switch_channel_expand_variables(channel, profile->notify_email_body); - } else { - body = switch_mprintf("%u second Voicemail from %s %s", message_len, caller_id_name, caller_id_number); - } - - switch_simple_email(vm_notify_email, from, header_string, body, NULL); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending notify message to %s\n", vm_notify_email); - switch_safe_free(body); - - if (headers != profile->notify_email_headers) { - switch_safe_free(headers); - } - } - - if (!insert_db) { - if (unlink(file_path) != 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "failed to delete file [%s]\n", file_path); - } - } + if (x_domain_root) { + switch_xml_free(x_domain_root); } switch_safe_free(file_path); @@ -2815,6 +3085,16 @@ static void do_web(vm_profile_t *profile, char *user, char *domain, char *host, } } + + +SWITCH_STANDARD_API(voicemail_inject_api_function) +{ + voicemail_inject(cmd); + + stream->write_function(stream, "%s", "+OK\n"); + return SWITCH_STATUS_SUCCESS; +} + SWITCH_STANDARD_API(voicemail_api_function) { int argc = 0; @@ -2941,6 +3221,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_voicemail_load) } SWITCH_ADD_API(commands_api_interface, "voicemail", "voicemail", voicemail_api_function, VOICEMAIL_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "voicemail_inject", "voicemail", voicemail_inject_api_function, ""); SWITCH_ADD_API(commands_api_interface, "vm_boxcount", "vm_boxcount", boxcount_api_function, BOXCOUNT_SYNTAX); /* indicate that the module should continue to be loaded */ diff --git a/src/switch_apr.c b/src/switch_apr.c index 34310d9e50..21f9242e30 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -294,6 +294,15 @@ SWITCH_DECLARE(switch_status_t) switch_file_seek(switch_file_t *thefile, switch_ return rv; } +SWITCH_DECLARE(switch_status_t) switch_file_copy(const char *from_path, + const char *to_path, + switch_fileperms_t perms, + switch_memory_pool_t *pool) +{ + return apr_file_copy(from_path, to_path, perms, pool); +} + + SWITCH_DECLARE(switch_status_t) switch_file_close(switch_file_t *thefile) { return apr_file_close(thefile); diff --git a/src/switch_channel.c b/src/switch_channel.c index 8bf02aa35a..34e85f5e2b 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -1951,6 +1951,15 @@ SWITCH_DECLARE(char *) switch_channel_build_param_string(switch_channel_t *chann return stream.data; } +SWITCH_DECLARE(switch_status_t) switch_channel_get_variables(switch_channel_t *channel, switch_event_t **event) +{ + switch_status_t status; + switch_mutex_lock(channel->profile_mutex); + status = switch_event_dup(event, channel->variables); + switch_mutex_lock(channel->profile_mutex); + return status; +} + SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t *channel) { switch_status_t status = SWITCH_STATUS_SUCCESS; diff --git a/src/switch_core.c b/src/switch_core.c index d86af82b3f..809cf5a2a4 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -786,9 +786,12 @@ SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload) 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); + switch_event_destroy(&my_params); continue; } + switch_event_destroy(&my_params); + for (ut = switch_xml_child(x_domain, "user"); ut; ut = ut->next) { const char *user_cidr = switch_xml_attr(ut, "cidr"); const char *id = switch_xml_attr(ut, "id");