#include "asterisk.h"
#include <ctype.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <time.h>
#include <dirent.h>
#include <locale.h>
#include "asterisk/paths.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/say.h"
#include "asterisk/module.h"
#include "asterisk/app.h"
#include "asterisk/manager.h"
#include "asterisk/dsp.h"
#include "asterisk/localtime.h"
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
#include "asterisk/callerid.h"
#include "asterisk/event.h"
Go to the source code of this file.
Data Structures | |
struct | b64_baseio |
Structure for base64 encoding. More... | |
struct | leave_vm_options |
Options for leaving voicemail with the voicemail() application. More... | |
struct | message_templates |
The list of e-mail templates. More... | |
struct | minivm_account |
struct | minivm_accounts |
struct | minivm_stats |
Structure for gathering statistics. More... | |
struct | minivm_template |
struct | minivm_zone |
Voicemail time zones. More... | |
struct | minivm_zones |
The list of e-mail time zones. More... | |
Defines | |
#define | ASTERISK_USERNAME "asterisk" |
#define | B64_BASELINELEN 72 |
#define | B64_BASEMAXINLINE 256 |
#define | DEFAULT_CHARSET "ISO-8859-1" |
#define | DEFAULT_DATEFORMAT "%A, %B %d, %Y at %r" |
#define | EOL "\r\n" |
#define | ERROR_LOCK_PATH -100 |
#define | FALSE 0 |
#define | HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n" |
#define | HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
#define | HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n" |
#define | MAX_DATETIME_FORMAT 512 |
#define | MAX_NUM_CID_CONTEXTS 10 |
#define | MVM_ALLOCED (1 << 13) |
#define | MVM_ENVELOPE (1 << 4) |
#define | MVM_OPERATOR (1 << 1) |
#define | MVM_PBXSKIP (1 << 9) |
#define | MVM_REALTIME (1 << 2) |
#define | MVM_REVIEW (1 << 0) |
#define | MVM_SVMAIL (1 << 3) |
#define | SENDMAIL "/usr/sbin/sendmail -t" |
Default mail command to mail voicemail. Change it with the mailcmd= command in voicemail.conf. | |
#define | SOUND_INTRO "vm-intro" |
#define | TRUE 1 |
#define | VOICEMAIL_CONFIG "minivm.conf" |
#define | VOICEMAIL_DIR_MODE 0700 |
Enumerations | |
enum | minivm_option_args { OPT_ARG_RECORDGAIN = 0, OPT_ARG_ARRAY_SIZE = 1 } |
enum | minivm_option_flags { OPT_SILENT = (1 << 0), OPT_BUSY_GREETING = (1 << 1), OPT_UNAVAIL_GREETING = (1 << 2), OPT_TEMP_GREETING = (1 << 3), OPT_NAME_GREETING = (1 << 4), OPT_RECORDGAIN = (1 << 5) } |
enum | mvm_messagetype { MVM_MESSAGE_EMAIL, MVM_MESSAGE_PAGE } |
Message types for notification. More... | |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | access_counter_file (char *directory, char *countername, int value, int operand) |
Access counter file, lock directory, read and possibly write it again changed. | |
static int | apply_general_options (struct ast_variable *var) |
Apply general configuration options. | |
static const char * | ast_str_encode_mime (struct ast_str **end, ssize_t maxlen, const char *charset, const char *start, size_t preamble, size_t postamble) |
static const char * | ast_str_quote (struct ast_str **buf, ssize_t maxlen, const char *from) |
static int | b64_inbuf (struct b64_baseio *bio, FILE *fi) |
static int | b64_inchar (struct b64_baseio *bio, FILE *fi) |
static int | b64_ochar (struct b64_baseio *bio, int c, FILE *so) |
static int | base_encode (char *filename, FILE *so) |
static int | check_dirpath (char *dest, int len, char *domain, char *username, char *folder) |
static int | check_mime (const char *str) |
static char * | complete_minivm_show_users (const char *line, const char *word, int pos, int state) |
static int | create_dirpath (char *dest, int len, char *domain, char *username, char *folder) |
static int | create_vmaccount (char *name, struct ast_variable *var, int realtime) |
Append new mailbox to mailbox list from configuration file. | |
static struct minivm_account * | find_account (const char *domain, const char *username, int createtemp) |
static struct minivm_account * | find_user_realtime (const char *domain, const char *username) |
static void | free_user (struct minivm_account *vmu) |
static void | free_zone (struct minivm_zone *z) |
Free Mini Voicemail timezone. | |
static int | get_date (char *s, int len) |
static char * | handle_minivm_list_templates (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
CLI routine for listing templates. | |
static char * | handle_minivm_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Reload cofiguration. | |
static char * | handle_minivm_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
CLI Show settings. | |
static char * | handle_minivm_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show stats. | |
static char * | handle_minivm_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
CLI command to list voicemail accounts. | |
static char * | handle_minivm_show_zones (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show a list of voicemail zones in the CLI. | |
static int | invent_message (struct ast_channel *chan, char *domain, char *username, int busy, char *ecodes) |
static int | leave_voicemail (struct ast_channel *chan, char *username, struct leave_vm_options *options) |
static int | load_config (int reload) |
Load minivoicemail configuration. | |
static int | load_module (void) |
Load mini voicemail module. | |
static int | make_dir (char *dest, int len, const char *domain, const char *username, const char *folder) |
static void | message_destroy_list (void) |
static int | message_template_build (const char *name, struct ast_variable *var) |
static struct minivm_template * | message_template_create (const char *name) |
static struct minivm_template * | message_template_find (const char *name) |
static void | message_template_free (struct minivm_template *template) |
static char * | message_template_parse_emailbody (const char *configuration) |
Parse emailbody template from configuration file. | |
static char * | message_template_parse_filebody (const char *filename) |
Read message template from file. | |
static int | minivm_accmess_exec (struct ast_channel *chan, const char *data) |
Record specific messages for voicemail account. | |
static int | minivm_account_func_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
${MINIVMACCOUNT()} Dialplan function - reads account data | |
static int | minivm_counter_func_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
${MINIVMCOUNTER()} Dialplan function - read counters | |
static int | minivm_counter_func_write (struct ast_channel *chan, const char *cmd, char *data, const char *value) |
${MINIVMCOUNTER()} Dialplan function - changes counter data | |
static int | minivm_delete_exec (struct ast_channel *chan, const char *data) |
static int | minivm_greet_exec (struct ast_channel *chan, const char *data) |
static int | minivm_mwi_exec (struct ast_channel *chan, const char *data) |
static int | minivm_notify_exec (struct ast_channel *chan, const char *data) |
static int | minivm_record_exec (struct ast_channel *chan, const char *data) |
static struct minivm_account * | mvm_user_alloc (void) |
static int | notify_new_message (struct ast_channel *chan, const char *templatename, struct minivm_account *vmu, const char *filename, long duration, const char *format, char *cidnum, char *cidname) |
static int | play_record_review (struct ast_channel *chan, char *playfile, char *recordfile, int maxtime, char *fmt, int outsidecaller, struct minivm_account *vmu, int *duration, int *sound_duration, const char *unlockdir, signed char record_gain) |
static void | populate_defaults (struct minivm_account *vmu) |
static void | prep_email_sub_vars (struct ast_channel *channel, const struct minivm_account *vmu, const char *cidnum, const char *cidname, const char *dur, const char *date, const char *counter) |
static void | queue_mwi_event (const char *mbx, const char *ctx, int urgent, int new, int old) |
static int | reload (void) |
Reload mini voicemail module. | |
static void | run_externnotify (struct ast_channel *chan, struct minivm_account *vmu) |
Run external notification for voicemail message. | |
static int | sendmail (struct minivm_template *template, struct minivm_account *vmu, char *cidnum, char *cidname, const char *filename, char *format, int duration, int attach_user_voicemail, enum mvm_messagetype type, const char *counter) |
static int | timezone_add (const char *zonename, const char *config) |
Add time zone to memory list. | |
static void | timezone_destroy_list (void) |
Clear list of timezones. | |
static int | unload_module (void) |
Unload mini voicemail module. | |
static int | vm_delete (char *file) |
static int | vm_lock_path (const char *path) |
lock directory | |
static void | vmaccounts_destroy_list (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Mini VoiceMail (A minimal Voicemail e-mail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, } |
static char * | app_minivm_accmess = "MinivmAccMess" |
static char * | app_minivm_delete = "MinivmDelete" |
static char * | app_minivm_greet = "MinivmGreet" |
static char * | app_minivm_mwi = "MinivmMWI" |
static char * | app_minivm_notify = "MinivmNotify" |
static char * | app_minivm_record = "MinivmRecord" |
static struct ast_module_info * | ast_module_info = &__mod_info |
static struct ast_cli_entry | cli_minivm [] |
CLI commands for Mini-voicemail. | |
static char | default_vmformat [80] |
static char | global_externnotify [160] |
static char | global_logfile [PATH_MAX] |
static char | global_mailcmd [160] |
static int | global_maxgreet |
static int | global_maxsilence |
static int | global_saydurationminfo |
static int | global_silencethreshold = 128 |
static struct minivm_stats | global_stats |
Statistics for voicemail. | |
static int | global_vmmaxmessage |
static int | global_vmminmessage |
static double | global_volgain |
static struct ast_flags | globalflags = {0} |
static struct ast_app_option | minivm_accmess_options [128] = { [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 't' ] = { .flag = OPT_TEMP_GREETING }, [ 'n' ] = { .flag = OPT_NAME_GREETING },} |
static struct ast_custom_function | minivm_account_function |
static struct ast_app_option | minivm_app_options [128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 },} |
static struct ast_custom_function | minivm_counter_function |
static ast_mutex_t | minivmlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
static FILE * | minivmlogfile |
static ast_mutex_t | minivmloglock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } |
static char | MVM_SPOOL_DIR [PATH_MAX] |
A voicemail system in small building blocks, working together based on the Comedian Mail voicemail system (app_voicemail.c).
Definition in file app_minivm.c.
#define ASTERISK_USERNAME "asterisk" |
Default username for sending mail is asterisk@localhost
Definition at line 534 of file app_minivm.c.
Referenced by actual_load_config().
#define B64_BASELINELEN 72 |
Line length for Base 64 endoded messages
Definition at line 524 of file app_minivm.c.
Referenced by b64_ochar().
#define B64_BASEMAXINLINE 256 |
Buffer size for Base 64 attachment encoding
Definition at line 523 of file app_minivm.c.
Referenced by b64_inbuf(), and base_encode().
#define DEFAULT_CHARSET "ISO-8859-1" |
#define DEFAULT_DATEFORMAT "%A, %B %d, %Y at %r" |
#define EOL "\r\n" |
#define ERROR_LOCK_PATH -100 |
Definition at line 530 of file app_minivm.c.
Referenced by close_mailbox(), copy_message(), count_messages(), minivm_record_exec(), open_mailbox(), resequence_mailbox(), save_to_folder(), vm_exec(), and vm_execmain().
#define FALSE 0 |
Definition at line 506 of file app_minivm.c.
Referenced by __sip_ack(), __sip_semi_ack(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), add_sdp(), AST_TEST_DEFINE(), ast_tzset(), build_peer(), cb_extensionstate(), cc_esc_publish_handler(), cc_handle_publish_error(), check_auth(), check_dirpath(), check_peer_ok(), check_pendings(), create_addr(), do_monitor(), expire_register(), find_sdp(), function_sippeer(), handle_invite_replaces(), handle_request_invite(), handle_request_notify(), handle_request_refer(), handle_request_subscribe(), handle_response(), handle_response_invite(), interpret_t38_parameters(), invent_message(), load_config(), minivm_accmess_exec(), minivm_counter_func_read(), minivm_counter_func_write(), parse_register_contact(), parse_sip_options(), pidf_validate_presence(), pidf_validate_tuple(), proc_session_timer(), process_crypto(), process_sdp(), process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), proxy_from_config(), proxy_update(), rcvfax_exec(), register_verify(), reload_config(), reqprep(), send_provisional_keepalive_full(), set_destination(), sip_addheader(), sip_answer(), sip_cc_monitor_request_cc(), sip_destroy_peer(), sip_devicestate(), sip_do_debug_peer(), sip_hangup(), sip_is_xml_parsable(), sip_monitor_instance_destructor(), sip_parse_register_line(), sip_pidf_validate(), sip_poke_noanswer(), sip_prune_realtime(), sip_read(), sip_sendhtml(), sip_set_history(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_show_inuse(), sip_show_settings(), sip_show_user(), sip_show_users(), sndfax_exec(), stop_session_timer(), time1(), time2(), time2sub(), transmit_audio(), transmit_invite(), transmit_provisional_response(), transmit_publish(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_response_with_sdp(), transmit_t38(), tzload(), tzparse(), update_call_counter(), and update_connectedline().
#define HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n" |
Referenced by handle_minivm_show_users().
#define HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" |
Referenced by handle_minivm_show_zones().
#define HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n" |
Referenced by handle_minivm_list_templates().
#define MAX_DATETIME_FORMAT 512 |
Definition at line 527 of file app_minivm.c.
#define MAX_NUM_CID_CONTEXTS 10 |
Definition at line 528 of file app_minivm.c.
Referenced by actual_load_config(), and play_message_callerid().
#define MVM_ALLOCED (1 << 13) |
Definition at line 516 of file app_minivm.c.
Referenced by find_account(), leave_voicemail(), minivm_accmess_exec(), minivm_account_func_read(), minivm_greet_exec(), and minivm_notify_exec().
#define MVM_ENVELOPE (1 << 4) |
Definition at line 514 of file app_minivm.c.
#define MVM_OPERATOR (1 << 1) |
Operator exit during voicemail recording
Definition at line 511 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), minivm_greet_exec(), and play_record_review().
#define MVM_PBXSKIP (1 << 9) |
Definition at line 515 of file app_minivm.c.
#define MVM_REALTIME (1 << 2) |
This user is a realtime account
Definition at line 512 of file app_minivm.c.
#define MVM_REVIEW (1 << 0) |
Review message
Definition at line 510 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and play_record_review().
#define MVM_SVMAIL (1 << 3) |
Definition at line 513 of file app_minivm.c.
#define SENDMAIL "/usr/sbin/sendmail -t" |
Default mail command to mail voicemail. Change it with the mailcmd= command in voicemail.conf.
Definition at line 520 of file app_minivm.c.
Referenced by actual_load_config(), and load_config().
#define SOUND_INTRO "vm-intro" |
#define TRUE 1 |
Definition at line 503 of file app_minivm.c.
Referenced by __sip_ack(), __sip_autodestruct(), __sip_semi_ack(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), add_sdp(), ast_tzset(), build_peer(), cc_esc_publish_handler(), check_dirpath(), check_peer_ok(), check_pendings(), create_addr(), find_account(), find_sdp(), find_user_realtime(), function_sippeer(), get_sip_pvt_byid_locked(), gmtload(), handle_request_invite(), handle_request_notify(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_peerpoke(), interpret_t38_parameters(), leave_voicemail(), load_config(), local_attended_transfer(), manager_mutestream(), message_template_create(), minivm_accmess_exec(), minivm_account_func_read(), minivm_greet_exec(), minivm_notify_exec(), parse_ok_contact(), parse_register_contact(), parse_sip_options(), pidf_validate_presence(), pidf_validate_tuple(), proc_session_timer(), process_crypto(), process_sdp(), process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), proxy_update(), rcvfax_exec(), reg_source_db(), register_verify(), reload_config(), reqprep(), respprep(), restart_session_timer(), set_destination(), sip_addheader(), sip_alloc(), sip_answer(), sip_cc_agent_respond(), sip_destroy(), sip_devicestate(), sip_do_debug_peer(), sip_hangup(), sip_indicate(), sip_is_xml_parsable(), sip_park_thread(), sip_pidf_validate(), sip_prune_realtime(), sip_reload(), sip_request_call(), sip_scheddestroy(), sip_set_history(), sip_set_udptl_peer(), sip_show_channel(), sip_show_inuse(), sip_show_user(), sip_show_users(), sip_unregister(), sip_write(), sndfax_exec(), spandsp_fax_start(), st_get_se(), start_session_timer(), stop_session_timer(), temp_peer(), time1(), time2(), transmit_audio(), transmit_cc_notify(), transmit_invite(), transmit_publish(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), transmit_response_with_sdp(), transmit_t38(), tzload(), and update_connectedline().
#define VOICEMAIL_CONFIG "minivm.conf" |
Definition at line 533 of file app_minivm.c.
#define VOICEMAIL_DIR_MODE 0700 |
enum minivm_option_args |
Definition at line 564 of file app_minivm.c.
00564 { 00565 OPT_ARG_RECORDGAIN = 0, 00566 OPT_ARG_ARRAY_SIZE = 1, 00567 };
enum minivm_option_flags |
OPT_SILENT | |
OPT_BUSY_GREETING | |
OPT_UNAVAIL_GREETING | |
OPT_TEMP_GREETING | |
OPT_NAME_GREETING | |
OPT_RECORDGAIN |
Definition at line 555 of file app_minivm.c.
00555 { 00556 OPT_SILENT = (1 << 0), 00557 OPT_BUSY_GREETING = (1 << 1), 00558 OPT_UNAVAIL_GREETING = (1 << 2), 00559 OPT_TEMP_GREETING = (1 << 3), 00560 OPT_NAME_GREETING = (1 << 4), 00561 OPT_RECORDGAIN = (1 << 5), 00562 };
enum mvm_messagetype |
Message types for notification.
Definition at line 537 of file app_minivm.c.
00537 { 00538 MVM_MESSAGE_EMAIL, 00539 MVM_MESSAGE_PAGE 00540 /* For trunk: MVM_MESSAGE_JABBER, */ 00541 };
static void __reg_module | ( | void | ) | [static] |
Definition at line 3582 of file app_minivm.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 3582 of file app_minivm.c.
static int access_counter_file | ( | char * | directory, | |
char * | countername, | |||
int | value, | |||
int | operand | |||
) | [static] |
Access counter file, lock directory, read and possibly write it again changed.
directory | Directory to crate file in | |
countername | filename | |
value | If set to zero, we only read the variable | |
operand | 0 to read, 1 to set new value, 2 to change |
Definition at line 3296 of file app_minivm.c.
References ast_debug, ast_log(), ast_unlock_path(), errno, LOG_ERROR, and vm_lock_path().
Referenced by minivm_counter_func_read(), and minivm_counter_func_write().
03297 { 03298 char filename[BUFSIZ]; 03299 char readbuf[BUFSIZ]; 03300 FILE *counterfile; 03301 int old = 0, counter = 0; 03302 03303 /* Lock directory */ 03304 if (vm_lock_path(directory)) { 03305 return -1; /* Could not lock directory */ 03306 } 03307 snprintf(filename, sizeof(filename), "%s/%s.counter", directory, countername); 03308 if (operand != 1) { 03309 counterfile = fopen(filename, "r"); 03310 if (counterfile) { 03311 if(fgets(readbuf, sizeof(readbuf), counterfile)) { 03312 ast_debug(3, "Read this string from counter file: %s\n", readbuf); 03313 old = counter = atoi(readbuf); 03314 } 03315 fclose(counterfile); 03316 } 03317 } 03318 switch (operand) { 03319 case 0: /* Read only */ 03320 ast_unlock_path(directory); 03321 ast_debug(2, "MINIVM Counter %s/%s: Value %d\n", directory, countername, counter); 03322 return counter; 03323 break; 03324 case 1: /* Set new value */ 03325 counter = value; 03326 break; 03327 case 2: /* Change value */ 03328 counter += value; 03329 if (counter < 0) /* Don't allow counters to fall below zero */ 03330 counter = 0; 03331 break; 03332 } 03333 03334 /* Now, write the new value to the file */ 03335 counterfile = fopen(filename, "w"); 03336 if (!counterfile) { 03337 ast_log(LOG_ERROR, "Could not open counter file for writing : %s - %s\n", filename, strerror(errno)); 03338 ast_unlock_path(directory); 03339 return -1; /* Could not open file for writing */ 03340 } 03341 fprintf(counterfile, "%d\n\n", counter); 03342 fclose(counterfile); 03343 ast_unlock_path(directory); 03344 ast_debug(2, "MINIVM Counter %s/%s: Old value %d New value %d\n", directory, countername, old, counter); 03345 return counter; 03346 }
static int apply_general_options | ( | struct ast_variable * | var | ) | [static] |
Apply general configuration options.
Definition at line 2778 of file app_minivm.c.
References ast_config_AST_LOG_DIR, ast_copy_string(), ast_log(), ast_set2_flag, ast_strlen_zero(), ast_true(), default_vmformat, global_externnotify, global_logfile, global_mailcmd, global_maxgreet, global_maxsilence, global_silencethreshold, global_vmmaxmessage, global_vmminmessage, globalflags, LOG_WARNING, MVM_OPERATOR, MVM_REVIEW, and var.
Referenced by load_config().
02779 { 02780 int error = 0; 02781 02782 while (var) { 02783 /* Mail command */ 02784 if (!strcmp(var->name, "mailcmd")) { 02785 ast_copy_string(global_mailcmd, var->value, sizeof(global_mailcmd)); /* User setting */ 02786 } else if (!strcmp(var->name, "maxgreet")) { 02787 global_maxgreet = atoi(var->value); 02788 } else if (!strcmp(var->name, "maxsilence")) { 02789 global_maxsilence = atoi(var->value); 02790 if (global_maxsilence > 0) 02791 global_maxsilence *= 1000; 02792 } else if (!strcmp(var->name, "logfile")) { 02793 if (!ast_strlen_zero(var->value) ) { 02794 if(*(var->value) == '/') 02795 ast_copy_string(global_logfile, var->value, sizeof(global_logfile)); 02796 else 02797 snprintf(global_logfile, sizeof(global_logfile), "%s/%s", ast_config_AST_LOG_DIR, var->value); 02798 } 02799 } else if (!strcmp(var->name, "externnotify")) { 02800 /* External voicemail notify application */ 02801 ast_copy_string(global_externnotify, var->value, sizeof(global_externnotify)); 02802 } else if (!strcmp(var->name, "silencetreshold")) { 02803 /* Silence treshold */ 02804 global_silencethreshold = atoi(var->value); 02805 } else if (!strcmp(var->name, "maxmessage")) { 02806 int x; 02807 if (sscanf(var->value, "%30d", &x) == 1) { 02808 global_vmmaxmessage = x; 02809 } else { 02810 error ++; 02811 ast_log(LOG_WARNING, "Invalid max message time length\n"); 02812 } 02813 } else if (!strcmp(var->name, "minmessage")) { 02814 int x; 02815 if (sscanf(var->value, "%30d", &x) == 1) { 02816 global_vmminmessage = x; 02817 if (global_maxsilence <= global_vmminmessage) 02818 ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 02819 } else { 02820 error ++; 02821 ast_log(LOG_WARNING, "Invalid min message time length\n"); 02822 } 02823 } else if (!strcmp(var->name, "format")) { 02824 ast_copy_string(default_vmformat, var->value, sizeof(default_vmformat)); 02825 } else if (!strcmp(var->name, "review")) { 02826 ast_set2_flag((&globalflags), ast_true(var->value), MVM_REVIEW); 02827 } else if (!strcmp(var->name, "operator")) { 02828 ast_set2_flag((&globalflags), ast_true(var->value), MVM_OPERATOR); 02829 } 02830 var = var->next; 02831 } 02832 return error; 02833 }
static const char* ast_str_encode_mime | ( | struct ast_str ** | end, | |
ssize_t | maxlen, | |||
const char * | charset, | |||
const char * | start, | |||
size_t | preamble, | |||
size_t | postamble | |||
) | [static] |
Definition at line 1158 of file app_minivm.c.
References ast_str_alloca, ast_str_append(), ast_str_buffer(), ast_str_reset(), ast_str_set(), and ast_str_strlen().
Referenced by make_email_file(), sendmail(), and sendpage().
01159 { 01160 struct ast_str *tmp = ast_str_alloca(80); 01161 int first_section = 1; 01162 *end = '\0'; 01163 01164 ast_str_reset(*end); 01165 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 01166 for (; *start; start++) { 01167 int need_encoding = 0; 01168 if (*start < 33 || *start > 126 || strchr("()<>@,:;/\"[]?.=_", *start)) { 01169 need_encoding = 1; 01170 } 01171 if ((first_section && need_encoding && preamble + ast_str_strlen(tmp) > 70) || 01172 (first_section && !need_encoding && preamble + ast_str_strlen(tmp) > 72) || 01173 (!first_section && need_encoding && ast_str_strlen(tmp) > 70) || 01174 (!first_section && !need_encoding && ast_str_strlen(tmp) > 72)) { 01175 /* Start new line */ 01176 ast_str_append(end, maxlen, "%s%s?=", first_section ? "" : " ", ast_str_buffer(tmp)); 01177 ast_str_set(&tmp, -1, "=?%s?Q?", charset); 01178 first_section = 0; 01179 } 01180 if (need_encoding && *start == ' ') { 01181 ast_str_append(&tmp, -1, "_"); 01182 } else if (need_encoding) { 01183 ast_str_append(&tmp, -1, "=%hhX", *start); 01184 } else { 01185 ast_str_append(&tmp, -1, "%c", *start); 01186 } 01187 } 01188 ast_str_append(end, maxlen, "%s%s?=%s", first_section ? "" : " ", ast_str_buffer(tmp), ast_str_strlen(tmp) + postamble > 74 ? " " : ""); 01189 return ast_str_buffer(*end); 01190 }
static const char* ast_str_quote | ( | struct ast_str ** | buf, | |
ssize_t | maxlen, | |||
const char * | from | |||
) | [static] |
Definition at line 1200 of file app_minivm.c.
References ast_str_append(), ast_str_buffer(), and ast_str_set().
Referenced by make_email_file(), sendmail(), and sendpage().
01201 { 01202 const char *ptr; 01203 01204 /* We're only ever passing 0 to maxlen, so short output isn't possible */ 01205 ast_str_set(buf, maxlen, "\""); 01206 for (ptr = from; *ptr; ptr++) { 01207 if (*ptr == '"' || *ptr == '\\') { 01208 ast_str_append(buf, maxlen, "\\%c", *ptr); 01209 } else { 01210 ast_str_append(buf, maxlen, "%c", *ptr); 01211 } 01212 } 01213 ast_str_append(buf, maxlen, "\""); 01214 01215 return ast_str_buffer(*buf); 01216 }
static int b64_inbuf | ( | struct b64_baseio * | bio, | |
FILE * | fi | |||
) | [static] |
Definition at line 836 of file app_minivm.c.
References b64_baseio::ateof, B64_BASEMAXINLINE, b64_baseio::iobuf, b64_baseio::iocp, and b64_baseio::iolen.
Referenced by b64_inchar().
00837 { 00838 int l; 00839 00840 if (bio->ateof) 00841 return 0; 00842 00843 if ((l = fread(bio->iobuf, 1, B64_BASEMAXINLINE,fi)) <= 0) { 00844 if (ferror(fi)) 00845 return -1; 00846 00847 bio->ateof = 1; 00848 return 0; 00849 } 00850 00851 bio->iolen= l; 00852 bio->iocp= 0; 00853 00854 return 1; 00855 }
static int b64_inchar | ( | struct b64_baseio * | bio, | |
FILE * | fi | |||
) | [static] |
Definition at line 859 of file app_minivm.c.
References b64_inbuf(), b64_baseio::iobuf, b64_baseio::iocp, and b64_baseio::iolen.
Referenced by base_encode().
00860 { 00861 if (bio->iocp >= bio->iolen) { 00862 if (!b64_inbuf(bio, fi)) 00863 return EOF; 00864 } 00865 00866 return bio->iobuf[bio->iocp++]; 00867 }
static int b64_ochar | ( | struct b64_baseio * | bio, | |
int | c, | |||
FILE * | so | |||
) | [static] |
Definition at line 871 of file app_minivm.c.
References B64_BASELINELEN, EOL, and b64_baseio::linelength.
Referenced by base_encode().
00872 { 00873 if (bio->linelength >= B64_BASELINELEN) { 00874 if (fputs(EOL,so) == EOF) 00875 return -1; 00876 00877 bio->linelength= 0; 00878 } 00879 00880 if (putc(((unsigned char) c), so) == EOF) 00881 return -1; 00882 00883 bio->linelength++; 00884 00885 return 1; 00886 }
static int base_encode | ( | char * | filename, | |
FILE * | so | |||
) | [static] |
Definition at line 890 of file app_minivm.c.
References ast_log(), B64_BASEMAXINLINE, b64_inchar(), b64_ochar(), EOL, errno, and LOG_WARNING.
Referenced by add_email_attachment(), and sendmail().
00891 { 00892 unsigned char dtable[B64_BASEMAXINLINE]; 00893 int i,hiteof= 0; 00894 FILE *fi; 00895 struct b64_baseio bio; 00896 00897 memset(&bio, 0, sizeof(bio)); 00898 bio.iocp = B64_BASEMAXINLINE; 00899 00900 if (!(fi = fopen(filename, "rb"))) { 00901 ast_log(LOG_WARNING, "Failed to open file: %s: %s\n", filename, strerror(errno)); 00902 return -1; 00903 } 00904 00905 for (i= 0; i<9; i++) { 00906 dtable[i]= 'A'+i; 00907 dtable[i+9]= 'J'+i; 00908 dtable[26+i]= 'a'+i; 00909 dtable[26+i+9]= 'j'+i; 00910 } 00911 for (i= 0; i < 8; i++) { 00912 dtable[i+18]= 'S'+i; 00913 dtable[26+i+18]= 's'+i; 00914 } 00915 for (i= 0; i < 10; i++) { 00916 dtable[52+i]= '0'+i; 00917 } 00918 dtable[62]= '+'; 00919 dtable[63]= '/'; 00920 00921 while (!hiteof){ 00922 unsigned char igroup[3], ogroup[4]; 00923 int c,n; 00924 00925 igroup[0]= igroup[1]= igroup[2]= 0; 00926 00927 for (n= 0; n < 3; n++) { 00928 if ((c = b64_inchar(&bio, fi)) == EOF) { 00929 hiteof= 1; 00930 break; 00931 } 00932 igroup[n]= (unsigned char)c; 00933 } 00934 00935 if (n> 0) { 00936 ogroup[0]= dtable[igroup[0]>>2]; 00937 ogroup[1]= dtable[((igroup[0]&3)<<4) | (igroup[1]>>4)]; 00938 ogroup[2]= dtable[((igroup[1]&0xF)<<2) | (igroup[2]>>6)]; 00939 ogroup[3]= dtable[igroup[2]&0x3F]; 00940 00941 if (n<3) { 00942 ogroup[3]= '='; 00943 00944 if (n<2) 00945 ogroup[2]= '='; 00946 } 00947 00948 for (i= 0;i<4;i++) 00949 b64_ochar(&bio, ogroup[i], so); 00950 } 00951 } 00952 00953 /* Put end of line - line feed */ 00954 if (fputs(EOL, so) == EOF) 00955 return 0; 00956 00957 fclose(fi); 00958 00959 return 1; 00960 }
static int check_dirpath | ( | char * | dest, | |
int | len, | |||
char * | domain, | |||
char * | username, | |||
char * | folder | |||
) | [static] |
Definition at line 1507 of file app_minivm.c.
References FALSE, make_dir(), and TRUE.
Referenced by leave_voicemail(), minivm_account_func_read(), and minivm_greet_exec().
01508 { 01509 struct stat filestat; 01510 make_dir(dest, len, domain, username, folder ? folder : ""); 01511 if (stat(dest, &filestat)== -1) 01512 return FALSE; 01513 else 01514 return TRUE; 01515 }
static int check_mime | ( | const char * | str | ) | [static] |
Definition at line 1129 of file app_minivm.c.
Referenced by make_email_file(), sendmail(), and sendpage().
01130 { 01131 for (; *str; str++) { 01132 if (*str > 126 || *str < 32 || strchr("()<>@,:;/\"[]?.=", *str)) { 01133 return 1; 01134 } 01135 } 01136 return 0; 01137 }
static char* complete_minivm_show_users | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 3017 of file app_minivm.c.
References AST_LIST_TRAVERSE, ast_strdup, minivm_account::domain, and minivm_account::list.
Referenced by handle_minivm_show_users().
03018 { 03019 int which = 0; 03020 int wordlen; 03021 struct minivm_account *vmu; 03022 const char *domain = ""; 03023 03024 /* 0 - voicemail; 1 - list; 2 - accounts; 3 - for; 4 - <domain> */ 03025 if (pos > 4) 03026 return NULL; 03027 if (pos == 3) 03028 return (state == 0) ? ast_strdup("for") : NULL; 03029 wordlen = strlen(word); 03030 AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) { 03031 if (!strncasecmp(word, vmu->domain, wordlen)) { 03032 if (domain && strcmp(domain, vmu->domain) && ++which > state) 03033 return ast_strdup(vmu->domain); 03034 /* ignore repeated domains ? */ 03035 domain = vmu->domain; 03036 } 03037 } 03038 return NULL; 03039 }
static int create_dirpath | ( | char * | dest, | |
int | len, | |||
char * | domain, | |||
char * | username, | |||
char * | folder | |||
) | [static] |
Definition at line 1526 of file app_minivm.c.
References ast_debug, ast_log(), ast_mkdir(), LOG_WARNING, and make_dir().
Referenced by add_email_attachment(), copy_message(), invent_message(), leave_voicemail(), minivm_counter_func_read(), minivm_counter_func_write(), open_mailbox(), and save_to_folder().
01527 { 01528 int res; 01529 make_dir(dest, len, domain, username, folder); 01530 if ((res = ast_mkdir(dest, 0777))) { 01531 ast_log(LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01532 return -1; 01533 } 01534 ast_debug(2, "Creating directory for %s@%s folder %s : %s\n", username, domain, folder, dest); 01535 return 0; 01536 }
static int create_vmaccount | ( | char * | name, | |
struct ast_variable * | var, | |||
int | realtime | |||
) | [static] |
Append new mailbox to mailbox list from configuration file.
Definition at line 2562 of file app_minivm.c.
References ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strdupa, ast_strlen_zero(), ast_variable_new(), minivm_account::domain, global_stats, minivm_account::list, LOG_ERROR, ast_variable::next, populate_defaults(), minivm_account::username, var, and minivm_stats::voicemailaccounts.
Referenced by find_user_realtime(), and load_config().
02563 { 02564 struct minivm_account *vmu; 02565 char *domain; 02566 char *username; 02567 char accbuf[BUFSIZ]; 02568 02569 ast_debug(3, "Creating %s account for [%s]\n", realtime ? "realtime" : "static", name); 02570 02571 ast_copy_string(accbuf, name, sizeof(accbuf)); 02572 username = accbuf; 02573 domain = strchr(accbuf, '@'); 02574 if (domain) { 02575 *domain = '\0'; 02576 domain++; 02577 } 02578 if (ast_strlen_zero(domain)) { 02579 ast_log(LOG_ERROR, "No domain given for mini-voicemail account %s. Not configured.\n", name); 02580 return 0; 02581 } 02582 02583 ast_debug(3, "Creating static account for user %s domain %s\n", username, domain); 02584 02585 /* Allocate user account */ 02586 vmu = ast_calloc(1, sizeof(*vmu)); 02587 if (!vmu) 02588 return 0; 02589 02590 ast_copy_string(vmu->domain, domain, sizeof(vmu->domain)); 02591 ast_copy_string(vmu->username, username, sizeof(vmu->username)); 02592 02593 populate_defaults(vmu); 02594 02595 ast_debug(3, "...Configuring account %s\n", name); 02596 02597 while (var) { 02598 ast_debug(3, "Configuring %s = \"%s\" for account %s\n", var->name, var->value, name); 02599 if (!strcasecmp(var->name, "serveremail")) { 02600 ast_copy_string(vmu->serveremail, var->value, sizeof(vmu->serveremail)); 02601 } else if (!strcasecmp(var->name, "email")) { 02602 ast_copy_string(vmu->email, var->value, sizeof(vmu->email)); 02603 } else if (!strcasecmp(var->name, "accountcode")) { 02604 ast_copy_string(vmu->accountcode, var->value, sizeof(vmu->accountcode)); 02605 } else if (!strcasecmp(var->name, "pincode")) { 02606 ast_copy_string(vmu->pincode, var->value, sizeof(vmu->pincode)); 02607 } else if (!strcasecmp(var->name, "domain")) { 02608 ast_copy_string(vmu->domain, var->value, sizeof(vmu->domain)); 02609 } else if (!strcasecmp(var->name, "language")) { 02610 ast_copy_string(vmu->language, var->value, sizeof(vmu->language)); 02611 } else if (!strcasecmp(var->name, "timezone")) { 02612 ast_copy_string(vmu->zonetag, var->value, sizeof(vmu->zonetag)); 02613 } else if (!strcasecmp(var->name, "externnotify")) { 02614 ast_copy_string(vmu->externnotify, var->value, sizeof(vmu->externnotify)); 02615 } else if (!strcasecmp(var->name, "etemplate")) { 02616 ast_copy_string(vmu->etemplate, var->value, sizeof(vmu->etemplate)); 02617 } else if (!strcasecmp(var->name, "ptemplate")) { 02618 ast_copy_string(vmu->ptemplate, var->value, sizeof(vmu->ptemplate)); 02619 } else if (!strcasecmp(var->name, "fullname")) { 02620 ast_copy_string(vmu->fullname, var->value, sizeof(vmu->fullname)); 02621 } else if (!strcasecmp(var->name, "setvar")) { 02622 char *varval; 02623 char *varname = ast_strdupa(var->value); 02624 struct ast_variable *tmpvar; 02625 02626 if (varname && (varval = strchr(varname, '='))) { 02627 *varval = '\0'; 02628 varval++; 02629 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 02630 tmpvar->next = vmu->chanvars; 02631 vmu->chanvars = tmpvar; 02632 } 02633 } 02634 } else if (!strcasecmp(var->name, "pager")) { 02635 ast_copy_string(vmu->pager, var->value, sizeof(vmu->pager)); 02636 } else if (!strcasecmp(var->name, "volgain")) { 02637 sscanf(var->value, "%30lf", &vmu->volgain); 02638 } else { 02639 ast_log(LOG_ERROR, "Unknown configuration option for minivm account %s : %s\n", name, var->name); 02640 } 02641 var = var->next; 02642 } 02643 ast_debug(3, "...Linking account %s\n", name); 02644 02645 AST_LIST_LOCK(&minivm_accounts); 02646 AST_LIST_INSERT_TAIL(&minivm_accounts, vmu, list); 02647 AST_LIST_UNLOCK(&minivm_accounts); 02648 02649 global_stats.voicemailaccounts++; 02650 02651 ast_debug(2, "MVM :: Created account %s@%s - tz %s etemplate %s %s\n", username, domain, ast_strlen_zero(vmu->zonetag) ? "" : vmu->zonetag, ast_strlen_zero(vmu->etemplate) ? "" : vmu->etemplate, realtime ? "(realtime)" : ""); 02652 return 0; 02653 }
static struct minivm_account* find_account | ( | const char * | domain, | |
const char * | username, | |||
int | createtemp | |||
) | [static] |
Definition at line 1052 of file app_minivm.c.
References ast_copy_string(), ast_debug, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_set2_flag, ast_strlen_zero(), minivm_account::domain, find_user_realtime(), minivm_account::list, LOG_NOTICE, MVM_ALLOCED, mvm_user_alloc(), TRUE, and minivm_account::username.
Referenced by leave_voicemail(), minivm_accmess_exec(), minivm_account_func_read(), minivm_counter_func_read(), minivm_counter_func_write(), minivm_greet_exec(), and minivm_notify_exec().
01053 { 01054 struct minivm_account *vmu = NULL, *cur; 01055 01056 01057 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 01058 ast_log(LOG_NOTICE, "No username or domain? \n"); 01059 return NULL; 01060 } 01061 ast_debug(3, "Looking for voicemail user %s in domain %s\n", username, domain); 01062 01063 AST_LIST_LOCK(&minivm_accounts); 01064 AST_LIST_TRAVERSE(&minivm_accounts, cur, list) { 01065 /* Is this the voicemail account we're looking for? */ 01066 if (!strcasecmp(domain, cur->domain) && !strcasecmp(username, cur->username)) 01067 break; 01068 } 01069 AST_LIST_UNLOCK(&minivm_accounts); 01070 01071 if (cur) { 01072 ast_debug(3, "Found account for %s@%s\n", username, domain); 01073 vmu = cur; 01074 01075 } else 01076 vmu = find_user_realtime(domain, username); 01077 01078 if (createtemp && !vmu) { 01079 /* Create a temporary user, send e-mail and be gone */ 01080 vmu = mvm_user_alloc(); 01081 ast_set2_flag(vmu, TRUE, MVM_ALLOCED); 01082 if (vmu) { 01083 ast_copy_string(vmu->username, username, sizeof(vmu->username)); 01084 ast_copy_string(vmu->domain, domain, sizeof(vmu->domain)); 01085 ast_debug(1, "Created temporary account\n"); 01086 } 01087 01088 } 01089 return vmu; 01090 }
static struct minivm_account * find_user_realtime | ( | const char * | domain, | |
const char * | username | |||
) | [static] |
Definition at line 1096 of file app_minivm.c.
References ast_copy_string(), ast_free, ast_load_realtime(), ast_variables_destroy(), create_vmaccount(), MAXHOSTNAMELEN, mvm_user_alloc(), populate_defaults(), SENTINEL, TRUE, minivm_account::username, and var.
Referenced by find_account(), and find_user().
01097 { 01098 struct ast_variable *var; 01099 struct minivm_account *retval; 01100 char name[MAXHOSTNAMELEN]; 01101 01102 retval = mvm_user_alloc(); 01103 if (!retval) 01104 return NULL; 01105 01106 if (username) 01107 ast_copy_string(retval->username, username, sizeof(retval->username)); 01108 01109 populate_defaults(retval); 01110 var = ast_load_realtime("minivm", "username", username, "domain", domain, SENTINEL); 01111 01112 if (!var) { 01113 ast_free(retval); 01114 return NULL; 01115 } 01116 01117 snprintf(name, sizeof(name), "%s@%s", username, domain); 01118 create_vmaccount(name, var, TRUE); 01119 01120 ast_variables_destroy(var); 01121 return retval; 01122 }
static void free_user | ( | struct minivm_account * | vmu | ) | [static] |
Definition at line 974 of file app_minivm.c.
References ast_free, ast_variables_destroy(), and minivm_account::chanvars.
Referenced by AST_TEST_DEFINE(), find_user_realtime(), forward_message(), free_vm_users(), leave_voicemail(), minivm_accmess_exec(), minivm_account_func_read(), minivm_greet_exec(), minivm_notify_exec(), and vm_execmain().
00975 { 00976 if (vmu->chanvars) 00977 ast_variables_destroy(vmu->chanvars); 00978 ast_free(vmu); 00979 }
static void free_zone | ( | struct minivm_zone * | z | ) | [static] |
Free Mini Voicemail timezone.
Definition at line 2656 of file app_minivm.c.
References ast_free.
Referenced by free_vm_zones(), and timezone_destroy_list().
02657 { 02658 ast_free(z); 02659 }
static int get_date | ( | char * | s, | |
int | len | |||
) | [static] |
Definition at line 962 of file app_minivm.c.
References ast_localtime(), ast_strftime(), and ast_tvnow().
Referenced by leave_voicemail(), and tds_log().
00963 { 00964 struct ast_tm tm; 00965 struct timeval now = ast_tvnow(); 00966 00967 ast_localtime(&now, &tm, NULL); 00968 return ast_strftime(s, len, "%a %b %e %r %Z %Y", &tm); 00969 }
static char* handle_minivm_list_templates | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
CLI routine for listing templates.
Definition at line 2976 of file app_minivm.c.
References ast_cli_args::argc, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HVLT_OUTPUT_FORMAT, minivm_account::list, and ast_cli_entry::usage.
02977 { 02978 struct minivm_template *this; 02979 #define HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n" 02980 int count = 0; 02981 02982 switch (cmd) { 02983 case CLI_INIT: 02984 e->command = "minivm list templates"; 02985 e->usage = 02986 "Usage: minivm list templates\n" 02987 " Lists message templates for e-mail, paging and IM\n"; 02988 return NULL; 02989 case CLI_GENERATE: 02990 return NULL; 02991 } 02992 02993 if (a->argc > 3) 02994 return CLI_SHOWUSAGE; 02995 02996 AST_LIST_LOCK(&message_templates); 02997 if (AST_LIST_EMPTY(&message_templates)) { 02998 ast_cli(a->fd, "There are no message templates defined\n"); 02999 AST_LIST_UNLOCK(&message_templates); 03000 return CLI_FAILURE; 03001 } 03002 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "Template name", "Charset", "Locale", "Attach media", "Subject"); 03003 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "-------------", "-------", "------", "------------", "-------"); 03004 AST_LIST_TRAVERSE(&message_templates, this, list) { 03005 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, this->name, 03006 this->charset ? this->charset : "-", 03007 this->locale ? this->locale : "-", 03008 this->attachment ? "Yes" : "No", 03009 this->subject ? this->subject : "-"); 03010 count++; 03011 } 03012 AST_LIST_UNLOCK(&message_templates); 03013 ast_cli(a->fd, "\n * Total: %d minivoicemail message templates\n", count); 03014 return CLI_SUCCESS; 03015 }
static char * handle_minivm_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Reload cofiguration.
Definition at line 3535 of file app_minivm.c.
References ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, reload, and ast_cli_entry::usage.
03536 { 03537 03538 switch (cmd) { 03539 case CLI_INIT: 03540 e->command = "minivm reload"; 03541 e->usage = 03542 "Usage: minivm reload\n" 03543 " Reload mini-voicemail configuration and reset statistics\n"; 03544 return NULL; 03545 case CLI_GENERATE: 03546 return NULL; 03547 } 03548 03549 reload(); 03550 ast_cli(a->fd, "\n-- Mini voicemail re-configured \n"); 03551 return CLI_SUCCESS; 03552 }
static char* handle_minivm_show_settings | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
CLI Show settings.
Definition at line 3127 of file app_minivm.c.
References ast_cli(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, default_vmformat, ast_cli_args::fd, global_externnotify, global_logfile, global_mailcmd, global_maxsilence, global_silencethreshold, global_vmmaxmessage, global_vmminmessage, globalflags, MVM_OPERATOR, MVM_REVIEW, and ast_cli_entry::usage.
03128 { 03129 switch (cmd) { 03130 case CLI_INIT: 03131 e->command = "minivm show settings"; 03132 e->usage = 03133 "Usage: minivm show settings\n" 03134 " Display Mini-Voicemail general settings\n"; 03135 return NULL; 03136 case CLI_GENERATE: 03137 return NULL; 03138 } 03139 03140 ast_cli(a->fd, "* Mini-Voicemail general settings\n"); 03141 ast_cli(a->fd, " -------------------------------\n"); 03142 ast_cli(a->fd, "\n"); 03143 ast_cli(a->fd, " Mail command (shell): %s\n", global_mailcmd); 03144 ast_cli(a->fd, " Max silence: %d\n", global_maxsilence); 03145 ast_cli(a->fd, " Silence threshold: %d\n", global_silencethreshold); 03146 ast_cli(a->fd, " Max message length (secs): %d\n", global_vmmaxmessage); 03147 ast_cli(a->fd, " Min message length (secs): %d\n", global_vmminmessage); 03148 ast_cli(a->fd, " Default format: %s\n", default_vmformat); 03149 ast_cli(a->fd, " Extern notify (shell): %s\n", global_externnotify); 03150 ast_cli(a->fd, " Logfile: %s\n", global_logfile[0] ? global_logfile : "<disabled>"); 03151 ast_cli(a->fd, " Operator exit: %s\n", ast_test_flag(&globalflags, MVM_OPERATOR) ? "Yes" : "No"); 03152 ast_cli(a->fd, " Message review: %s\n", ast_test_flag(&globalflags, MVM_REVIEW) ? "Yes" : "No"); 03153 03154 ast_cli(a->fd, "\n"); 03155 return CLI_SUCCESS; 03156 }
static char* handle_minivm_show_stats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Show stats.
Definition at line 3159 of file app_minivm.c.
References ast_cli(), ast_localtime(), ast_strftime(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, global_stats, minivm_stats::lastreceived, minivm_stats::receivedmessages, minivm_stats::reset, minivm_stats::templates, minivm_stats::timezones, ast_cli_entry::usage, and minivm_stats::voicemailaccounts.
03160 { 03161 struct ast_tm timebuf; 03162 char buf[BUFSIZ]; 03163 03164 switch (cmd) { 03165 03166 case CLI_INIT: 03167 e->command = "minivm show stats"; 03168 e->usage = 03169 "Usage: minivm show stats\n" 03170 " Display Mini-Voicemail counters\n"; 03171 return NULL; 03172 case CLI_GENERATE: 03173 return NULL; 03174 } 03175 03176 ast_cli(a->fd, "* Mini-Voicemail statistics\n"); 03177 ast_cli(a->fd, " -------------------------\n"); 03178 ast_cli(a->fd, "\n"); 03179 ast_cli(a->fd, " Voicemail accounts: %5d\n", global_stats.voicemailaccounts); 03180 ast_cli(a->fd, " Templates: %5d\n", global_stats.templates); 03181 ast_cli(a->fd, " Timezones: %5d\n", global_stats.timezones); 03182 if (global_stats.receivedmessages == 0) { 03183 ast_cli(a->fd, " Received messages since last reset: <none>\n"); 03184 } else { 03185 ast_cli(a->fd, " Received messages since last reset: %d\n", global_stats.receivedmessages); 03186 ast_localtime(&global_stats.lastreceived, &timebuf, NULL); 03187 ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf); 03188 ast_cli(a->fd, " Last received voicemail: %s\n", buf); 03189 } 03190 ast_localtime(&global_stats.reset, &timebuf, NULL); 03191 ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf); 03192 ast_cli(a->fd, " Last reset: %s\n", buf); 03193 03194 ast_cli(a->fd, "\n"); 03195 return CLI_SUCCESS; 03196 }
static char* handle_minivm_show_users | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
CLI command to list voicemail accounts.
Definition at line 3042 of file app_minivm.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, minivm_account::attachfmt, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_minivm_show_users(), minivm_account::domain, minivm_account::etemplate, ast_cli_args::fd, minivm_account::fullname, HMSU_OUTPUT_FORMAT, ast_cli_args::line, minivm_account::list, ast_cli_args::n, ast_cli_args::pos, minivm_account::ptemplate, ast_cli_entry::usage, minivm_account::username, ast_cli_args::word, and minivm_account::zonetag.
03043 { 03044 struct minivm_account *vmu; 03045 #define HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n" 03046 int count = 0; 03047 03048 switch (cmd) { 03049 case CLI_INIT: 03050 e->command = "minivm list accounts"; 03051 e->usage = 03052 "Usage: minivm list accounts\n" 03053 " Lists all mailboxes currently set up\n"; 03054 return NULL; 03055 case CLI_GENERATE: 03056 return complete_minivm_show_users(a->line, a->word, a->pos, a->n); 03057 } 03058 03059 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 03060 return CLI_SHOWUSAGE; 03061 if ((a->argc == 5) && strcmp(a->argv[3],"for")) 03062 return CLI_SHOWUSAGE; 03063 03064 AST_LIST_LOCK(&minivm_accounts); 03065 if (AST_LIST_EMPTY(&minivm_accounts)) { 03066 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 03067 AST_LIST_UNLOCK(&minivm_accounts); 03068 return CLI_FAILURE; 03069 } 03070 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "User", "E-Template", "P-template", "Zone", "Format", "Full name"); 03071 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "----", "----------", "----------", "----", "------", "---------"); 03072 AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) { 03073 char tmp[256] = ""; 03074 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(a->argv[4], vmu->domain))) { 03075 count++; 03076 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->username, vmu->domain); 03077 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, tmp, vmu->etemplate ? vmu->etemplate : "-", 03078 vmu->ptemplate ? vmu->ptemplate : "-", 03079 vmu->zonetag ? vmu->zonetag : "-", 03080 vmu->attachfmt ? vmu->attachfmt : "-", 03081 vmu->fullname); 03082 } 03083 } 03084 AST_LIST_UNLOCK(&minivm_accounts); 03085 ast_cli(a->fd, "\n * Total: %d minivoicemail accounts\n", count); 03086 return CLI_SUCCESS; 03087 }
static char* handle_minivm_show_zones | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Show a list of voicemail zones in the CLI.
Definition at line 3090 of file app_minivm.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, HMSZ_OUTPUT_FORMAT, minivm_account::list, minivm_zone::msg_format, minivm_zone::name, minivm_zone::timezone, and ast_cli_entry::usage.
03091 { 03092 struct minivm_zone *zone; 03093 #define HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 03094 char *res = CLI_SUCCESS; 03095 03096 switch (cmd) { 03097 case CLI_INIT: 03098 e->command = "minivm list zones"; 03099 e->usage = 03100 "Usage: minivm list zones\n" 03101 " Lists zone message formats\n"; 03102 return NULL; 03103 case CLI_GENERATE: 03104 return NULL; 03105 } 03106 03107 if (a->argc != e->args) 03108 return CLI_SHOWUSAGE; 03109 03110 AST_LIST_LOCK(&minivm_zones); 03111 if (!AST_LIST_EMPTY(&minivm_zones)) { 03112 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 03113 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "----", "--------", "--------------"); 03114 AST_LIST_TRAVERSE(&minivm_zones, zone, list) { 03115 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 03116 } 03117 } else { 03118 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 03119 res = CLI_FAILURE; 03120 } 03121 AST_LIST_UNLOCK(&minivm_zones); 03122 03123 return res; 03124 }
static int invent_message | ( | struct ast_channel * | chan, | |
char * | domain, | |||
char * | username, | |||
int | busy, | |||
char * | ecodes | |||
) | [static] |
Definition at line 1542 of file app_minivm.c.
References ast_debug, ast_fileexists(), ast_say_digit_str(), ast_streamfile(), ast_waitstream(), FALSE, and ast_channel::language.
Referenced by minivm_greet_exec().
01543 { 01544 int res; 01545 char fn[PATH_MAX]; 01546 01547 ast_debug(2, "Still preparing to play message ...\n"); 01548 01549 snprintf(fn, sizeof(fn), "%s%s/%s/greet", MVM_SPOOL_DIR, domain, username); 01550 01551 if (ast_fileexists(fn, NULL, NULL) > 0) { 01552 res = ast_streamfile(chan, fn, chan->language); 01553 if (res) 01554 return -1; 01555 res = ast_waitstream(chan, ecodes); 01556 if (res) 01557 return res; 01558 } else { 01559 int numericusername = 1; 01560 char *i = username; 01561 01562 ast_debug(2, "No personal prompts. Using default prompt set for language\n"); 01563 01564 while (*i) { 01565 ast_debug(2, "Numeric? Checking %c\n", *i); 01566 if (!isdigit(*i)) { 01567 numericusername = FALSE; 01568 break; 01569 } 01570 i++; 01571 } 01572 01573 if (numericusername) { 01574 if (ast_streamfile(chan, "vm-theperson", chan->language)) 01575 return -1; 01576 if ((res = ast_waitstream(chan, ecodes))) 01577 return res; 01578 01579 res = ast_say_digit_str(chan, username, ecodes, chan->language); 01580 if (res) 01581 return res; 01582 } else { 01583 if (ast_streamfile(chan, "vm-theextensionis", chan->language)) 01584 return -1; 01585 if ((res = ast_waitstream(chan, ecodes))) 01586 return res; 01587 } 01588 } 01589 01590 res = ast_streamfile(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language); 01591 if (res) 01592 return -1; 01593 res = ast_waitstream(chan, ecodes); 01594 return res; 01595 }
static int leave_voicemail | ( | struct ast_channel * | chan, | |
char * | username, | |||
struct leave_vm_options * | options | |||
) | [static] |
Definition at line 1846 of file app_minivm.c.
References minivm_account::accountcode, ast_callerid_merge(), ast_copy_string(), ast_debug, ast_filedelete(), ast_fileexists(), ast_localtime(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_streamfile(), ast_strftime(), ast_strlen_zero(), ast_test_flag, ast_tvnow(), ast_verb, ast_waitstream(), minivm_account::attachfmt, ast_channel::caller, check_dirpath(), ast_channel::context, create_dirpath(), default_vmformat, minivm_account::domain, errno, ast_channel::exten, find_account(), free_user(), get_date(), global_stats, global_vmmaxmessage, global_vmminmessage, ast_party_caller::id, ast_channel::language, minivm_stats::lastreceived, LOG_ERROR, LOG_WARNING, ast_channel::macrocontext, minivmlogfile, minivmloglock, MVM_ALLOCED, ast_channel::name, ast_party_id::name, ast_party_id::number, pbx_builtin_setvar_helper(), play_record_review(), ast_channel::priority, minivm_stats::receivedmessages, leave_vm_options::record_gain, S_COR, ast_party_number::str, ast_party_name::str, TRUE, ast_party_number::valid, and ast_party_name::valid.
Referenced by advanced_options(), forward_message(), minivm_record_exec(), and vm_exec().
01847 { 01848 char tmptxtfile[PATH_MAX]; 01849 char callerid[256]; 01850 FILE *txt; 01851 int res = 0, txtdes; 01852 int duration = 0; 01853 int sound_duration = 0; 01854 char date[256]; 01855 char tmpdir[PATH_MAX]; 01856 char ext_context[256] = ""; 01857 char fmt[80]; 01858 char *domain; 01859 char tmp[256] = ""; 01860 struct minivm_account *vmu; 01861 int userdir; 01862 01863 ast_copy_string(tmp, username, sizeof(tmp)); 01864 username = tmp; 01865 domain = strchr(tmp, '@'); 01866 if (domain) { 01867 *domain = '\0'; 01868 domain++; 01869 } 01870 01871 if (!(vmu = find_account(domain, username, TRUE))) { 01872 /* We could not find user, let's exit */ 01873 ast_log(LOG_ERROR, "Can't allocate temporary account for '%s@%s'\n", username, domain); 01874 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01875 return 0; 01876 } 01877 01878 /* Setup pre-file if appropriate */ 01879 if (strcmp(vmu->domain, "localhost")) 01880 snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain); 01881 else 01882 ast_copy_string(ext_context, vmu->domain, sizeof(ext_context)); 01883 01884 /* The meat of recording the message... All the announcements and beeps have been played*/ 01885 if (ast_strlen_zero(vmu->attachfmt)) 01886 ast_copy_string(fmt, default_vmformat, sizeof(fmt)); 01887 else 01888 ast_copy_string(fmt, vmu->attachfmt, sizeof(fmt)); 01889 01890 if (ast_strlen_zero(fmt)) { 01891 ast_log(LOG_WARNING, "No format for saving voicemail? Default %s\n", default_vmformat); 01892 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01893 return res; 01894 } 01895 01896 userdir = check_dirpath(tmpdir, sizeof(tmpdir), vmu->domain, username, "tmp"); 01897 01898 /* If we have no user directory, use generic temporary directory */ 01899 if (!userdir) { 01900 create_dirpath(tmpdir, sizeof(tmpdir), "0000_minivm_temp", "mediafiles", ""); 01901 ast_debug(3, "Creating temporary directory %s\n", tmpdir); 01902 } 01903 01904 01905 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 01906 01907 /* XXX This file needs to be in temp directory */ 01908 txtdes = mkstemp(tmptxtfile); 01909 if (txtdes < 0) { 01910 ast_log(LOG_ERROR, "Unable to create message file %s: %s\n", tmptxtfile, strerror(errno)); 01911 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 01912 if (!res) 01913 res = ast_waitstream(chan, ""); 01914 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01915 return res; 01916 } 01917 01918 if (res >= 0) { 01919 /* Unless we're *really* silent, try to send the beep */ 01920 res = ast_streamfile(chan, "beep", chan->language); 01921 if (!res) 01922 res = ast_waitstream(chan, ""); 01923 } 01924 01925 /* OEJ XXX Maybe this can be turned into a log file? Hmm. */ 01926 /* Store information */ 01927 ast_debug(2, "Open file for metadata: %s\n", tmptxtfile); 01928 01929 res = play_record_review(chan, NULL, tmptxtfile, global_vmmaxmessage, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain); 01930 01931 txt = fdopen(txtdes, "w+"); 01932 if (!txt) { 01933 ast_log(LOG_WARNING, "Error opening text file for output\n"); 01934 } else { 01935 struct ast_tm tm; 01936 struct timeval now = ast_tvnow(); 01937 char timebuf[30]; 01938 char logbuf[BUFSIZ]; 01939 get_date(date, sizeof(date)); 01940 ast_localtime(&now, &tm, NULL); 01941 ast_strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &tm); 01942 01943 ast_callerid_merge(callerid, sizeof(callerid), 01944 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 01945 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 01946 "Unknown"); 01947 snprintf(logbuf, sizeof(logbuf), 01948 /* "Mailbox:domain:macrocontext:exten:priority:callerchan:callerid:origdate:origtime:duration:durationstatus:accountcode" */ 01949 "%s:%s:%s:%s:%d:%s:%s:%s:%s:%d:%s:%s\n", 01950 username, 01951 chan->context, 01952 chan->macrocontext, 01953 chan->exten, 01954 chan->priority, 01955 chan->name, 01956 callerid, 01957 date, 01958 timebuf, 01959 duration, 01960 duration < global_vmminmessage ? "IGNORED" : "OK", 01961 vmu->accountcode 01962 ); 01963 fprintf(txt, "%s", logbuf); 01964 if (minivmlogfile) { 01965 ast_mutex_lock(&minivmloglock); 01966 fprintf(minivmlogfile, "%s", logbuf); 01967 ast_mutex_unlock(&minivmloglock); 01968 } 01969 01970 if (sound_duration < global_vmminmessage) { 01971 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, global_vmminmessage); 01972 fclose(txt); 01973 ast_filedelete(tmptxtfile, NULL); 01974 unlink(tmptxtfile); 01975 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01976 return 0; 01977 } 01978 fclose(txt); /* Close log file */ 01979 if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 01980 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 01981 unlink(tmptxtfile); 01982 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01983 if(ast_test_flag(vmu, MVM_ALLOCED)) 01984 free_user(vmu); 01985 return 0; 01986 } 01987 01988 /* Set channel variables for the notify application */ 01989 pbx_builtin_setvar_helper(chan, "MVM_FILENAME", tmptxtfile); 01990 snprintf(timebuf, sizeof(timebuf), "%d", duration); 01991 pbx_builtin_setvar_helper(chan, "MVM_DURATION", timebuf); 01992 pbx_builtin_setvar_helper(chan, "MVM_FORMAT", fmt); 01993 01994 } 01995 global_stats.lastreceived = ast_tvnow(); 01996 global_stats.receivedmessages++; 01997 #if 0 01998 /* Go ahead and delete audio files from system, they're not needed any more */ 01999 if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 02000 ast_filedelete(tmptxtfile, NULL); 02001 /* Even not being used at the moment, it's better to convert ast_log to ast_debug anyway */ 02002 ast_debug(2, "-_-_- Deleted audio file after notification :: %s \n", tmptxtfile); 02003 } 02004 #endif 02005 02006 if (res > 0) 02007 res = 0; 02008 02009 if(ast_test_flag(vmu, MVM_ALLOCED)) 02010 free_user(vmu); 02011 02012 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS"); 02013 return res; 02014 }
static int load_config | ( | int | reload | ) | [static] |
Load minivoicemail configuration.
Definition at line 2836 of file app_minivm.c.
References apply_general_options(), ast_category_browse(), ast_config_destroy(), ast_config_load, ast_copy_string(), ast_debug, ast_dsp_get_threshold_from_settings(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set2_flag, ast_strlen_zero(), ast_tvnow(), ast_variable_browse(), ast_variable_retrieve(), chanvar, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, create_vmaccount(), default_vmformat, errno, FALSE, global_externnotify, global_logfile, global_mailcmd, global_maxgreet, global_maxsilence, global_saydurationminfo, global_silencethreshold, global_stats, global_vmmaxmessage, global_vmminmessage, globalflags, LOG_ERROR, LOG_WARNING, message_destroy_list(), message_template_build(), message_template_find(), message_template_parse_emailbody(), minivmlock, minivmlogfile, MVM_OPERATOR, MVM_REVIEW, SENDMAIL, THRESHOLD_SILENCE, timezone_add(), timezone_destroy_list(), TRUE, var, vmaccounts_destroy_list(), and VOICEMAIL_CONFIG.
02837 { 02838 struct ast_config *cfg; 02839 struct ast_variable *var; 02840 char *cat; 02841 const char *chanvar; 02842 int error = 0; 02843 struct minivm_template *template; 02844 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 02845 02846 cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags); 02847 if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 02848 return 0; 02849 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 02850 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 02851 return 0; 02852 } 02853 02854 ast_mutex_lock(&minivmlock); 02855 02856 /* Destroy lists to reconfigure */ 02857 message_destroy_list(); /* Destroy list of voicemail message templates */ 02858 timezone_destroy_list(); /* Destroy list of timezones */ 02859 vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */ 02860 ast_debug(2, "Destroyed memory objects...\n"); 02861 02862 /* First, set some default settings */ 02863 global_externnotify[0] = '\0'; 02864 global_logfile[0] = '\0'; 02865 global_vmmaxmessage = 2000; 02866 global_maxgreet = 2000; 02867 global_vmminmessage = 0; 02868 strcpy(global_mailcmd, SENDMAIL); 02869 global_maxsilence = 0; 02870 global_saydurationminfo = 2; 02871 ast_copy_string(default_vmformat, "wav", sizeof(default_vmformat)); 02872 ast_set2_flag((&globalflags), FALSE, MVM_REVIEW); 02873 ast_set2_flag((&globalflags), FALSE, MVM_OPERATOR); 02874 /* Reset statistics */ 02875 memset(&global_stats, 0, sizeof(global_stats)); 02876 global_stats.reset = ast_tvnow(); 02877 02878 global_silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 02879 02880 /* Make sure we could load configuration file */ 02881 if (!cfg) { 02882 ast_log(LOG_WARNING, "Failed to load configuration file. Module activated with default settings.\n"); 02883 ast_mutex_unlock(&minivmlock); 02884 return 0; 02885 } 02886 02887 ast_debug(2, "Loaded configuration file, now parsing\n"); 02888 02889 /* General settings */ 02890 02891 cat = ast_category_browse(cfg, NULL); 02892 while (cat) { 02893 ast_debug(3, "Found configuration section [%s]\n", cat); 02894 if (!strcasecmp(cat, "general")) { 02895 /* Nothing right now */ 02896 error += apply_general_options(ast_variable_browse(cfg, cat)); 02897 } else if (!strncasecmp(cat, "template-", 9)) { 02898 /* Template */ 02899 char *name = cat + 9; 02900 02901 /* Now build and link template to list */ 02902 error += message_template_build(name, ast_variable_browse(cfg, cat)); 02903 } else { 02904 var = ast_variable_browse(cfg, cat); 02905 if (!strcasecmp(cat, "zonemessages")) { 02906 /* Timezones in this context */ 02907 while (var) { 02908 timezone_add(var->name, var->value); 02909 var = var->next; 02910 } 02911 } else { 02912 /* Create mailbox from this */ 02913 error += create_vmaccount(cat, var, FALSE); 02914 } 02915 } 02916 /* Find next section in configuration file */ 02917 cat = ast_category_browse(cfg, cat); 02918 } 02919 02920 /* Configure the default email template */ 02921 message_template_build("email-default", NULL); 02922 template = message_template_find("email-default"); 02923 02924 /* Load date format config for voicemail mail */ 02925 if ((chanvar = ast_variable_retrieve(cfg, "general", "emaildateformat"))) 02926 ast_copy_string(template->dateformat, chanvar, sizeof(template->dateformat)); 02927 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailfromstring"))) 02928 ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress)); 02929 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailaaddress"))) 02930 ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail)); 02931 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailcharset"))) 02932 ast_copy_string(template->charset, chanvar, sizeof(template->charset)); 02933 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailsubject"))) 02934 ast_copy_string(template->subject, chanvar, sizeof(template->subject)); 02935 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailbody"))) 02936 template->body = message_template_parse_emailbody(chanvar); 02937 template->attachment = TRUE; 02938 02939 message_template_build("pager-default", NULL); 02940 template = message_template_find("pager-default"); 02941 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 02942 ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress)); 02943 if ((chanvar = ast_variable_retrieve(cfg, "general", "pageraddress"))) 02944 ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail)); 02945 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagercharset"))) 02946 ast_copy_string(template->charset, chanvar, sizeof(template->charset)); 02947 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagersubject"))) 02948 ast_copy_string(template->subject, chanvar,sizeof(template->subject)); 02949 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerbody"))) 02950 template->body = message_template_parse_emailbody(chanvar); 02951 template->attachment = FALSE; 02952 02953 if (error) 02954 ast_log(LOG_ERROR, "--- A total of %d errors found in mini-voicemail configuration\n", error); 02955 02956 ast_mutex_unlock(&minivmlock); 02957 ast_config_destroy(cfg); 02958 02959 /* Close log file if it's open and disabled */ 02960 if(minivmlogfile) 02961 fclose(minivmlogfile); 02962 02963 /* Open log file if it's enabled */ 02964 if(!ast_strlen_zero(global_logfile)) { 02965 minivmlogfile = fopen(global_logfile, "a"); 02966 if(!minivmlogfile) 02967 ast_log(LOG_ERROR, "Failed to open minivm log file %s : %s\n", global_logfile, strerror(errno)); 02968 if (minivmlogfile) 02969 ast_debug(3, "Opened log file %s \n", global_logfile); 02970 } 02971 02972 return 0; 02973 }
static int load_module | ( | void | ) | [static] |
Load mini voicemail module.
Definition at line 3501 of file app_minivm.c.
References ARRAY_LEN, ast_cli_register_multiple(), ast_config_AST_SPOOL_DIR, ast_custom_function_register, ast_register_application_xml, cli_minivm, load_config(), minivm_accmess_exec(), minivm_account_function, minivm_counter_function, minivm_delete_exec(), minivm_greet_exec(), minivm_mwi_exec(), minivm_notify_exec(), and minivm_record_exec().
03502 { 03503 int res; 03504 03505 res = ast_register_application_xml(app_minivm_record, minivm_record_exec); 03506 res = ast_register_application_xml(app_minivm_greet, minivm_greet_exec); 03507 res = ast_register_application_xml(app_minivm_notify, minivm_notify_exec); 03508 res = ast_register_application_xml(app_minivm_delete, minivm_delete_exec); 03509 res = ast_register_application_xml(app_minivm_accmess, minivm_accmess_exec); 03510 res = ast_register_application_xml(app_minivm_mwi, minivm_mwi_exec); 03511 03512 ast_custom_function_register(&minivm_account_function); 03513 ast_custom_function_register(&minivm_counter_function); 03514 if (res) 03515 return(res); 03516 03517 if ((res = load_config(0))) 03518 return(res); 03519 03520 ast_cli_register_multiple(cli_minivm, ARRAY_LEN(cli_minivm)); 03521 03522 /* compute the location of the voicemail spool directory */ 03523 snprintf(MVM_SPOOL_DIR, sizeof(MVM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 03524 03525 return res; 03526 }
static int make_dir | ( | char * | dest, | |
int | len, | |||
const char * | domain, | |||
const char * | username, | |||
const char * | folder | |||
) | [static] |
Definition at line 1493 of file app_minivm.c.
References ast_strlen_zero().
Referenced by check_dirpath(), copy_message(), create_dirpath(), make_email_file(), manager_list_voicemail_users(), notify_new_message(), and prep_email_sub_vars().
01494 { 01495 return snprintf(dest, len, "%s%s/%s%s%s", MVM_SPOOL_DIR, domain, username, ast_strlen_zero(folder) ? "" : "/", folder ? folder : ""); 01496 }
static void message_destroy_list | ( | void | ) | [static] |
Definition at line 823 of file app_minivm.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, minivm_account::list, and message_template_free().
Referenced by load_config(), and unload_module().
00824 { 00825 struct minivm_template *this; 00826 AST_LIST_LOCK(&message_templates); 00827 while ((this = AST_LIST_REMOVE_HEAD(&message_templates, list))) { 00828 message_template_free(this); 00829 } 00830 00831 AST_LIST_UNLOCK(&message_templates); 00832 }
static int message_template_build | ( | const char * | name, | |
struct ast_variable * | var | |||
) | [static] |
Definition at line 738 of file app_minivm.c.
References ast_copy_string(), ast_debug, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_true(), global_stats, minivm_account::list, LOG_ERROR, message_template_create(), message_template_parse_emailbody(), message_template_parse_filebody(), minivm_stats::templates, and var.
Referenced by load_config().
00739 { 00740 struct minivm_template *template; 00741 int error = 0; 00742 00743 template = message_template_create(name); 00744 if (!template) { 00745 ast_log(LOG_ERROR, "Out of memory, can't allocate message template object %s.\n", name); 00746 return -1; 00747 } 00748 00749 while (var) { 00750 ast_debug(3, "Configuring template option %s = \"%s\" for template %s\n", var->name, var->value, name); 00751 if (!strcasecmp(var->name, "fromaddress")) { 00752 ast_copy_string(template->fromaddress, var->value, sizeof(template->fromaddress)); 00753 } else if (!strcasecmp(var->name, "fromemail")) { 00754 ast_copy_string(template->serveremail, var->value, sizeof(template->serveremail)); 00755 } else if (!strcasecmp(var->name, "subject")) { 00756 ast_copy_string(template->subject, var->value, sizeof(template->subject)); 00757 } else if (!strcasecmp(var->name, "locale")) { 00758 ast_copy_string(template->locale, var->value, sizeof(template->locale)); 00759 } else if (!strcasecmp(var->name, "attachmedia")) { 00760 template->attachment = ast_true(var->value); 00761 } else if (!strcasecmp(var->name, "dateformat")) { 00762 ast_copy_string(template->dateformat, var->value, sizeof(template->dateformat)); 00763 } else if (!strcasecmp(var->name, "charset")) { 00764 ast_copy_string(template->charset, var->value, sizeof(template->charset)); 00765 } else if (!strcasecmp(var->name, "templatefile")) { 00766 if (template->body) 00767 ast_free(template->body); 00768 template->body = message_template_parse_filebody(var->value); 00769 if (!template->body) { 00770 ast_log(LOG_ERROR, "Error reading message body definition file %s\n", var->value); 00771 error++; 00772 } 00773 } else if (!strcasecmp(var->name, "messagebody")) { 00774 if (template->body) 00775 ast_free(template->body); 00776 template->body = message_template_parse_emailbody(var->value); 00777 if (!template->body) { 00778 ast_log(LOG_ERROR, "Error parsing message body definition:\n %s\n", var->value); 00779 error++; 00780 } 00781 } else { 00782 ast_log(LOG_ERROR, "Unknown message template configuration option \"%s=%s\"\n", var->name, var->value); 00783 error++; 00784 } 00785 var = var->next; 00786 } 00787 if (error) 00788 ast_log(LOG_ERROR, "-- %d errors found parsing message template definition %s\n", error, name); 00789 00790 AST_LIST_LOCK(&message_templates); 00791 AST_LIST_INSERT_TAIL(&message_templates, template, list); 00792 AST_LIST_UNLOCK(&message_templates); 00793 00794 global_stats.templates++; 00795 00796 return error; 00797 }
static struct minivm_template* message_template_create | ( | const char * | name | ) | [static] |
Definition at line 708 of file app_minivm.c.
References ast_calloc, ast_copy_string(), DEFAULT_CHARSET, DEFAULT_DATEFORMAT, and TRUE.
Referenced by message_template_build().
00709 { 00710 struct minivm_template *template; 00711 00712 template = ast_calloc(1, sizeof(*template)); 00713 if (!template) 00714 return NULL; 00715 00716 /* Set some defaults for templates */ 00717 ast_copy_string(template->name, name, sizeof(template->name)); 00718 ast_copy_string(template->dateformat, DEFAULT_DATEFORMAT, sizeof(template->dateformat)); 00719 ast_copy_string(template->charset, DEFAULT_CHARSET, sizeof(template->charset)); 00720 ast_copy_string(template->subject, "New message in mailbox ${MVM_USERNAME}@${MVM_DOMAIN}", sizeof(template->subject)); 00721 template->attachment = TRUE; 00722 00723 return template; 00724 }
static struct minivm_template* message_template_find | ( | const char * | name | ) | [static] |
Definition at line 801 of file app_minivm.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), and minivm_account::list.
Referenced by load_config(), and notify_new_message().
00802 { 00803 struct minivm_template *this, *res = NULL; 00804 00805 if (ast_strlen_zero(name)) 00806 return NULL; 00807 00808 AST_LIST_LOCK(&message_templates); 00809 AST_LIST_TRAVERSE(&message_templates, this, list) { 00810 if (!strcasecmp(this->name, name)) { 00811 res = this; 00812 break; 00813 } 00814 } 00815 AST_LIST_UNLOCK(&message_templates); 00816 00817 return res; 00818 }
static void message_template_free | ( | struct minivm_template * | template | ) | [static] |
Definition at line 728 of file app_minivm.c.
References ast_free, and minivm_template::body.
Referenced by message_destroy_list().
00729 { 00730 if (template->body) 00731 ast_free(template->body); 00732 00733 ast_free (template); 00734 }
static char * message_template_parse_emailbody | ( | const char * | body | ) | [static] |
Parse emailbody template from configuration file.
Definition at line 2751 of file app_minivm.c.
References ast_log(), ast_strdup, emailbody, len(), and LOG_NOTICE.
Referenced by load_config(), and message_template_build().
02752 { 02753 char *tmpread, *tmpwrite; 02754 char *emailbody = ast_strdup(configuration); 02755 02756 /* substitute strings \t and \n into the apropriate characters */ 02757 tmpread = tmpwrite = emailbody; 02758 while ((tmpwrite = strchr(tmpread,'\\'))) { 02759 int len = strlen("\n"); 02760 switch (tmpwrite[1]) { 02761 case 'n': 02762 memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1); 02763 strncpy(tmpwrite, "\n", len); 02764 break; 02765 case 't': 02766 memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1); 02767 strncpy(tmpwrite, "\t", len); 02768 break; 02769 default: 02770 ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]); 02771 } 02772 tmpread = tmpwrite + len; 02773 } 02774 return emailbody; 02775 }
static char * message_template_parse_filebody | ( | const char * | filename | ) | [static] |
Read message template from file.
Definition at line 2711 of file app_minivm.c.
References ast_calloc, ast_config_AST_CONFIG_DIR, ast_copy_string(), ast_debug, ast_log(), ast_strlen_zero(), and LOG_ERROR.
Referenced by message_template_build().
02711 { 02712 char buf[BUFSIZ * 6]; 02713 char readbuf[BUFSIZ]; 02714 char filenamebuf[BUFSIZ]; 02715 char *writepos; 02716 char *messagebody; 02717 FILE *fi; 02718 int lines = 0; 02719 02720 if (ast_strlen_zero(filename)) 02721 return NULL; 02722 if (*filename == '/') 02723 ast_copy_string(filenamebuf, filename, sizeof(filenamebuf)); 02724 else 02725 snprintf(filenamebuf, sizeof(filenamebuf), "%s/%s", ast_config_AST_CONFIG_DIR, filename); 02726 02727 if (!(fi = fopen(filenamebuf, "r"))) { 02728 ast_log(LOG_ERROR, "Can't read message template from file: %s\n", filenamebuf); 02729 return NULL; 02730 } 02731 writepos = buf; 02732 while (fgets(readbuf, sizeof(readbuf), fi)) { 02733 lines ++; 02734 if (writepos != buf) { 02735 *writepos = '\n'; /* Replace EOL with new line */ 02736 writepos++; 02737 } 02738 ast_copy_string(writepos, readbuf, sizeof(buf) - (writepos - buf)); 02739 writepos += strlen(readbuf) - 1; 02740 } 02741 fclose(fi); 02742 messagebody = ast_calloc(1, strlen(buf + 1)); 02743 ast_copy_string(messagebody, buf, strlen(buf) + 1); 02744 ast_debug(4, "---> Size of allocation %d\n", (int) strlen(buf + 1) ); 02745 ast_debug(4, "---> Done reading message template : \n%s\n---- END message template--- \n", messagebody); 02746 02747 return messagebody; 02748 }
static int minivm_accmess_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Record specific messages for voicemail account.
Definition at line 2459 of file app_minivm.c.
References ast_channel::_state, ARRAY_LEN, ast_answer(), ast_app_parse_options(), ast_app_separate_args, ast_copy_string(), ast_debug, ast_log(), AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, default_vmformat, minivm_account::domain, FALSE, find_account(), minivm_account::flags, free_user(), global_maxgreet, LOG_ERROR, LOG_WARNING, minivm_accmess_options, MVM_ALLOCED, OPT_ARG_ARRAY_SIZE, OPT_BUSY_GREETING, OPT_NAME_GREETING, OPT_TEMP_GREETING, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), play_record_review(), prompt, TRUE, and minivm_account::username.
Referenced by load_module().
02460 { 02461 int argc = 0; 02462 char *argv[2]; 02463 char filename[PATH_MAX]; 02464 char tmp[PATH_MAX]; 02465 char *domain; 02466 char *tmpptr = NULL; 02467 struct minivm_account *vmu; 02468 char *username; 02469 struct ast_flags flags = { 0 }; 02470 char *opts[OPT_ARG_ARRAY_SIZE]; 02471 int error = FALSE; 02472 char *message = NULL; 02473 char *prompt = NULL; 02474 int duration; 02475 02476 if (ast_strlen_zero(data)) { 02477 ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n"); 02478 error = TRUE; 02479 } else 02480 tmpptr = ast_strdupa((char *)data); 02481 if (!error) { 02482 if (!tmpptr) { 02483 ast_log(LOG_ERROR, "Out of memory\n"); 02484 error = TRUE; 02485 } else 02486 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02487 } 02488 02489 if (argc <=1) { 02490 ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n"); 02491 error = TRUE; 02492 } 02493 if (!error && strlen(argv[1]) > 1) { 02494 ast_log(LOG_ERROR, "MinivmAccmess can only handle one option at a time. Bad option string: %s\n", argv[1]); 02495 error = TRUE; 02496 } 02497 02498 if (!error && ast_app_parse_options(minivm_accmess_options, &flags, opts, argv[1])) { 02499 ast_log(LOG_ERROR, "Can't parse option %s\n", argv[1]); 02500 error = TRUE; 02501 } 02502 02503 if (error) { 02504 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02505 return -1; 02506 } 02507 02508 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02509 username = tmp; 02510 domain = strchr(tmp, '@'); 02511 if (domain) { 02512 *domain = '\0'; 02513 domain++; 02514 } 02515 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 02516 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]); 02517 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02518 return -1; 02519 } 02520 02521 if(!(vmu = find_account(domain, username, TRUE))) { 02522 /* We could not find user, let's exit */ 02523 ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain); 02524 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02525 return -1; 02526 } 02527 02528 /* Answer channel if it's not already answered */ 02529 if (chan->_state != AST_STATE_UP) 02530 ast_answer(chan); 02531 02532 /* Here's where the action is */ 02533 if (ast_test_flag(&flags, OPT_BUSY_GREETING)) { 02534 message = "busy"; 02535 prompt = "vm-rec-busy"; 02536 } else if (ast_test_flag(&flags, OPT_UNAVAIL_GREETING)) { 02537 message = "unavailable"; 02538 prompt = "vm-rec-unv"; 02539 } else if (ast_test_flag(&flags, OPT_TEMP_GREETING)) { 02540 message = "temp"; 02541 prompt = "vm-rec-temp"; 02542 } else if (ast_test_flag(&flags, OPT_NAME_GREETING)) { 02543 message = "greet"; 02544 prompt = "vm-rec-name"; 02545 } 02546 snprintf(filename,sizeof(filename), "%s%s/%s/%s", MVM_SPOOL_DIR, vmu->domain, vmu->username, message); 02547 /* Maybe we should check the result of play_record_review ? */ 02548 play_record_review(chan, prompt, filename, global_maxgreet, default_vmformat, 0, vmu, &duration, NULL, NULL, FALSE); 02549 02550 ast_debug(1, "Recorded new %s message in %s (duration %d)\n", message, filename, duration); 02551 02552 if(ast_test_flag(vmu, MVM_ALLOCED)) 02553 free_user(vmu); 02554 02555 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "SUCCESS"); 02556 02557 /* Ok, we're ready to rock and roll. Return to dialplan */ 02558 return 0; 02559 }
static int minivm_account_func_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
${MINIVMACCOUNT()} Dialplan function - reads account data
Definition at line 3199 of file app_minivm.c.
References minivm_account::accountcode, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, minivm_account::chanvars, check_dirpath(), minivm_account::domain, minivm_account::email, minivm_account::etemplate, find_account(), free_user(), minivm_account::fullname, minivm_account::language, LOG_ERROR, MVM_ALLOCED, minivm_account::pager, minivm_account::pincode, minivm_account::ptemplate, TRUE, minivm_account::username, var, and minivm_account::zonetag.
03200 { 03201 struct minivm_account *vmu; 03202 char *username, *domain, *colname; 03203 03204 if (!(username = ast_strdupa(data))) { 03205 ast_log(LOG_ERROR, "Memory Error!\n"); 03206 return -1; 03207 } 03208 03209 if ((colname = strchr(username, ':'))) { 03210 *colname = '\0'; 03211 colname++; 03212 } else { 03213 colname = "path"; 03214 } 03215 if ((domain = strchr(username, '@'))) { 03216 *domain = '\0'; 03217 domain++; 03218 } 03219 if (ast_strlen_zero(username) || ast_strlen_zero(domain)) { 03220 ast_log(LOG_ERROR, "This function needs a username and a domain: username@domain\n"); 03221 return 0; 03222 } 03223 03224 if (!(vmu = find_account(domain, username, TRUE))) 03225 return 0; 03226 03227 if (!strcasecmp(colname, "hasaccount")) { 03228 ast_copy_string(buf, (ast_test_flag(vmu, MVM_ALLOCED) ? "0" : "1"), len); 03229 } else if (!strcasecmp(colname, "fullname")) { 03230 ast_copy_string(buf, vmu->fullname, len); 03231 } else if (!strcasecmp(colname, "email")) { 03232 if (!ast_strlen_zero(vmu->email)) 03233 ast_copy_string(buf, vmu->email, len); 03234 else 03235 snprintf(buf, len, "%s@%s", vmu->username, vmu->domain); 03236 } else if (!strcasecmp(colname, "pager")) { 03237 ast_copy_string(buf, vmu->pager, len); 03238 } else if (!strcasecmp(colname, "etemplate")) { 03239 if (!ast_strlen_zero(vmu->etemplate)) 03240 ast_copy_string(buf, vmu->etemplate, len); 03241 else 03242 ast_copy_string(buf, "email-default", len); 03243 } else if (!strcasecmp(colname, "language")) { 03244 ast_copy_string(buf, vmu->language, len); 03245 } else if (!strcasecmp(colname, "timezone")) { 03246 ast_copy_string(buf, vmu->zonetag, len); 03247 } else if (!strcasecmp(colname, "ptemplate")) { 03248 if (!ast_strlen_zero(vmu->ptemplate)) 03249 ast_copy_string(buf, vmu->ptemplate, len); 03250 else 03251 ast_copy_string(buf, "email-default", len); 03252 } else if (!strcasecmp(colname, "accountcode")) { 03253 ast_copy_string(buf, vmu->accountcode, len); 03254 } else if (!strcasecmp(colname, "pincode")) { 03255 ast_copy_string(buf, vmu->pincode, len); 03256 } else if (!strcasecmp(colname, "path")) { 03257 check_dirpath(buf, len, vmu->domain, vmu->username, NULL); 03258 } else { /* Look in channel variables */ 03259 struct ast_variable *var; 03260 03261 for (var = vmu->chanvars ; var ; var = var->next) 03262 if (!strcmp(var->name, colname)) { 03263 ast_copy_string(buf, var->value, len); 03264 break; 03265 } 03266 } 03267 03268 if(ast_test_flag(vmu, MVM_ALLOCED)) 03269 free_user(vmu); 03270 03271 return 0; 03272 }
static int minivm_counter_func_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
${MINIVMCOUNTER()} Dialplan function - read counters
Definition at line 3349 of file app_minivm.c.
References access_counter_file(), ast_log(), ast_strdupa, ast_strlen_zero(), create_dirpath(), minivm_account::domain, FALSE, find_account(), LOG_ERROR, LOG_WARNING, and minivm_account::username.
03350 { 03351 char *username, *domain, *countername; 03352 struct minivm_account *vmu = NULL; 03353 char userpath[BUFSIZ]; 03354 int res; 03355 03356 *buf = '\0'; 03357 03358 if (!(username = ast_strdupa(data))) { /* Copy indata to local buffer */ 03359 ast_log(LOG_WARNING, "Memory error!\n"); 03360 return -1; 03361 } 03362 if ((countername = strchr(username, ':'))) { 03363 *countername = '\0'; 03364 countername++; 03365 } 03366 03367 if ((domain = strchr(username, '@'))) { 03368 *domain = '\0'; 03369 domain++; 03370 } 03371 03372 /* If we have neither username nor domain now, let's give up */ 03373 if (ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03374 ast_log(LOG_ERROR, "No account given\n"); 03375 return -1; 03376 } 03377 03378 if (ast_strlen_zero(countername)) { 03379 ast_log(LOG_ERROR, "This function needs two arguments: Account:countername\n"); 03380 return -1; 03381 } 03382 03383 /* We only have a domain, no username */ 03384 if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03385 domain = username; 03386 username = NULL; 03387 } 03388 03389 /* If we can't find account or if the account is temporary, return. */ 03390 if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) { 03391 ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain); 03392 return 0; 03393 } 03394 03395 create_dirpath(userpath, sizeof(userpath), domain, username, NULL); 03396 03397 /* We have the path, now read the counter file */ 03398 res = access_counter_file(userpath, countername, 0, 0); 03399 if (res >= 0) 03400 snprintf(buf, len, "%d", res); 03401 return 0; 03402 }
static int minivm_counter_func_write | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
const char * | value | |||
) | [static] |
${MINIVMCOUNTER()} Dialplan function - changes counter data
Definition at line 3405 of file app_minivm.c.
References access_counter_file(), ast_log(), ast_strdupa, ast_strlen_zero(), create_dirpath(), minivm_account::domain, FALSE, find_account(), LOG_ERROR, LOG_WARNING, and minivm_account::username.
03406 { 03407 char *username, *domain, *countername, *operand; 03408 char userpath[BUFSIZ]; 03409 struct minivm_account *vmu; 03410 int change = 0; 03411 int operation = 0; 03412 03413 if(!value) 03414 return -1; 03415 change = atoi(value); 03416 03417 if (!(username = ast_strdupa(data))) { /* Copy indata to local buffer */ 03418 ast_log(LOG_WARNING, "Memory error!\n"); 03419 return -1; 03420 } 03421 03422 if ((countername = strchr(username, ':'))) { 03423 *countername = '\0'; 03424 countername++; 03425 } 03426 if ((operand = strchr(countername, ':'))) { 03427 *operand = '\0'; 03428 operand++; 03429 } 03430 03431 if ((domain = strchr(username, '@'))) { 03432 *domain = '\0'; 03433 domain++; 03434 } 03435 03436 /* If we have neither username nor domain now, let's give up */ 03437 if (ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03438 ast_log(LOG_ERROR, "No account given\n"); 03439 return -1; 03440 } 03441 03442 /* We only have a domain, no username */ 03443 if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03444 domain = username; 03445 username = NULL; 03446 } 03447 03448 if (ast_strlen_zero(operand) || ast_strlen_zero(countername)) { 03449 ast_log(LOG_ERROR, "Writing to this function requires three arguments: Account:countername:operand\n"); 03450 return -1; 03451 } 03452 03453 /* If we can't find account or if the account is temporary, return. */ 03454 if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) { 03455 ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain); 03456 return 0; 03457 } 03458 03459 create_dirpath(userpath, sizeof(userpath), domain, username, NULL); 03460 /* Now, find out our operator */ 03461 if (*operand == 'i') /* Increment */ 03462 operation = 2; 03463 else if (*operand == 'd') { 03464 change = change * -1; 03465 operation = 2; 03466 } else if (*operand == 's') 03467 operation = 1; 03468 else { 03469 ast_log(LOG_ERROR, "Unknown operator: %s\n", operand); 03470 return -1; 03471 } 03472 03473 /* We have the path, now read the counter file */ 03474 access_counter_file(userpath, countername, change, operation); 03475 return 0; 03476 }
static int minivm_delete_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 2421 of file app_minivm.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_fileexists(), ast_log(), ast_strlen_zero(), LOG_ERROR, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and vm_delete().
Referenced by load_module().
02422 { 02423 int res = 0; 02424 char filename[BUFSIZ]; 02425 02426 if (!ast_strlen_zero(data)) { 02427 ast_copy_string(filename, (char *) data, sizeof(filename)); 02428 } else { 02429 ast_channel_lock(chan); 02430 ast_copy_string(filename, pbx_builtin_getvar_helper(chan, "MVM_FILENAME"), sizeof(filename)); 02431 ast_channel_unlock(chan); 02432 } 02433 02434 if (ast_strlen_zero(filename)) { 02435 ast_log(LOG_ERROR, "No filename given in application arguments or channel variable MVM_FILENAME\n"); 02436 return res; 02437 } 02438 02439 /* Go ahead and delete audio files from system, they're not needed any more */ 02440 /* We should look for both audio and text files here */ 02441 if (ast_fileexists(filename, NULL, NULL) > 0) { 02442 res = vm_delete(filename); 02443 if (res) { 02444 ast_debug(2, "Can't delete file: %s\n", filename); 02445 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED"); 02446 } else { 02447 ast_debug(2, "Deleted voicemail file :: %s \n", filename); 02448 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "SUCCESS"); 02449 } 02450 } else { 02451 ast_debug(2, "Filename does not exist: %s\n", filename); 02452 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED"); 02453 } 02454 02455 return res; 02456 }
static int minivm_greet_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 2225 of file app_minivm.c.
References ast_channel::_state, ARRAY_LEN, ast_answer(), ast_app_parse_options(), ast_app_separate_args, ast_copy_flags, ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_play_and_wait(), ast_set_flag, AST_STATE_UP, ast_stopstream(), ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitstream(), check_dirpath(), minivm_account::domain, minivm_account::exit, find_account(), minivm_account::flags, free_user(), invent_message(), LOG_ERROR, minivm_app_options, MVM_ALLOCED, MVM_OPERATOR, OPT_ARG_ARRAY_SIZE, OPT_BUSY_GREETING, OPT_SILENT, OPT_UNAVAIL_GREETING, pbx_builtin_setvar_helper(), S_COR, SOUND_INTRO, TRUE, and minivm_account::username.
Referenced by load_module().
02226 { 02227 struct leave_vm_options leave_options = { 0, '\0'}; 02228 int argc; 02229 char *argv[2]; 02230 struct ast_flags flags = { 0 }; 02231 char *opts[OPT_ARG_ARRAY_SIZE]; 02232 int res = 0; 02233 int ausemacro = 0; 02234 int ousemacro = 0; 02235 int ouseexten = 0; 02236 char tmp[PATH_MAX]; 02237 char dest[PATH_MAX]; 02238 char prefile[PATH_MAX] = ""; 02239 char tempfile[PATH_MAX] = ""; 02240 char ext_context[256] = ""; 02241 char *domain; 02242 char ecodes[16] = "#"; 02243 char *tmpptr; 02244 struct minivm_account *vmu; 02245 char *username = argv[0]; 02246 02247 if (ast_strlen_zero(data)) { 02248 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 02249 return -1; 02250 } 02251 tmpptr = ast_strdupa((char *)data); 02252 if (!tmpptr) { 02253 ast_log(LOG_ERROR, "Out of memory\n"); 02254 return -1; 02255 } 02256 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02257 02258 if (argc == 2) { 02259 if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) 02260 return -1; 02261 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING ); 02262 } 02263 02264 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02265 username = tmp; 02266 domain = strchr(tmp, '@'); 02267 if (domain) { 02268 *domain = '\0'; 02269 domain++; 02270 } 02271 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 02272 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument: %s\n", argv[0]); 02273 return -1; 02274 } 02275 ast_debug(1, "Trying to find configuration for user %s in domain %s\n", username, domain); 02276 02277 if (!(vmu = find_account(domain, username, TRUE))) { 02278 ast_log(LOG_ERROR, "Could not allocate memory. \n"); 02279 return -1; 02280 } 02281 02282 /* Answer channel if it's not already answered */ 02283 if (chan->_state != AST_STATE_UP) 02284 ast_answer(chan); 02285 02286 /* Setup pre-file if appropriate */ 02287 if (strcmp(vmu->domain, "localhost")) 02288 snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain); 02289 else 02290 ast_copy_string(ext_context, vmu->domain, sizeof(ext_context)); 02291 02292 if (ast_test_flag(&leave_options, OPT_BUSY_GREETING)) { 02293 res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "busy"); 02294 if (res) 02295 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", MVM_SPOOL_DIR, vmu->domain, username); 02296 } else if (ast_test_flag(&leave_options, OPT_UNAVAIL_GREETING)) { 02297 res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "unavail"); 02298 if (res) 02299 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", MVM_SPOOL_DIR, vmu->domain, username); 02300 } 02301 /* Check for temporary greeting - it overrides busy and unavail */ 02302 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", MVM_SPOOL_DIR, vmu->domain, username); 02303 if (!(res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "temp"))) { 02304 ast_debug(2, "Temporary message directory does not exist, using default (%s)\n", tempfile); 02305 ast_copy_string(prefile, tempfile, sizeof(prefile)); 02306 } 02307 ast_debug(2, "Preparing to play message ...\n"); 02308 02309 /* Check current or macro-calling context for special extensions */ 02310 if (ast_test_flag(vmu, MVM_OPERATOR)) { 02311 if (!ast_strlen_zero(vmu->exit)) { 02312 if (ast_exists_extension(chan, vmu->exit, "o", 1, 02313 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 02314 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 02315 ouseexten = 1; 02316 } 02317 } else if (ast_exists_extension(chan, chan->context, "o", 1, 02318 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 02319 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 02320 ouseexten = 1; 02321 } 02322 else if (!ast_strlen_zero(chan->macrocontext) 02323 && ast_exists_extension(chan, chan->macrocontext, "o", 1, 02324 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 02325 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 02326 ousemacro = 1; 02327 } 02328 } 02329 02330 if (!ast_strlen_zero(vmu->exit)) { 02331 if (ast_exists_extension(chan, vmu->exit, "a", 1, 02332 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 02333 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 02334 } 02335 } else if (ast_exists_extension(chan, chan->context, "a", 1, 02336 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 02337 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 02338 } else if (!ast_strlen_zero(chan->macrocontext) 02339 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 02340 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 02341 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 02342 ausemacro = 1; 02343 } 02344 02345 res = 0; /* Reset */ 02346 /* Play the beginning intro if desired */ 02347 if (!ast_strlen_zero(prefile)) { 02348 if (ast_streamfile(chan, prefile, chan->language) > -1) 02349 res = ast_waitstream(chan, ecodes); 02350 } else { 02351 ast_debug(2, "%s doesn't exist, doing what we can\n", prefile); 02352 res = invent_message(chan, vmu->domain, username, ast_test_flag(&leave_options, OPT_BUSY_GREETING), ecodes); 02353 } 02354 if (res < 0) { 02355 ast_debug(2, "Hang up during prefile playback\n"); 02356 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED"); 02357 if(ast_test_flag(vmu, MVM_ALLOCED)) 02358 free_user(vmu); 02359 return -1; 02360 } 02361 if (res == '#') { 02362 /* On a '#' we skip the instructions */ 02363 ast_set_flag(&leave_options, OPT_SILENT); 02364 res = 0; 02365 } 02366 if (!res && !ast_test_flag(&leave_options, OPT_SILENT)) { 02367 res = ast_streamfile(chan, SOUND_INTRO, chan->language); 02368 if (!res) 02369 res = ast_waitstream(chan, ecodes); 02370 if (res == '#') { 02371 ast_set_flag(&leave_options, OPT_SILENT); 02372 res = 0; 02373 } 02374 } 02375 if (res > 0) 02376 ast_stopstream(chan); 02377 /* Check for a '*' here in case the caller wants to escape from voicemail to something 02378 other than the operator -- an automated attendant or mailbox login for example */ 02379 if (res == '*') { 02380 chan->exten[0] = 'a'; 02381 chan->exten[1] = '\0'; 02382 if (!ast_strlen_zero(vmu->exit)) { 02383 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 02384 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 02385 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 02386 } 02387 chan->priority = 0; 02388 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT"); 02389 res = 0; 02390 } else if (res == '0') { /* Check for a '0' here */ 02391 if(ouseexten || ousemacro) { 02392 chan->exten[0] = 'o'; 02393 chan->exten[1] = '\0'; 02394 if (!ast_strlen_zero(vmu->exit)) { 02395 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 02396 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 02397 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 02398 } 02399 ast_play_and_wait(chan, "transfer"); 02400 chan->priority = 0; 02401 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT"); 02402 } 02403 res = 0; 02404 } else if (res < 0) { 02405 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED"); 02406 res = -1; 02407 } else 02408 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "SUCCESS"); 02409 02410 if(ast_test_flag(vmu, MVM_ALLOCED)) 02411 free_user(vmu); 02412 02413 02414 /* Ok, we're ready to rock and roll. Return to dialplan */ 02415 return res; 02416 02417 }
static int minivm_mwi_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 2043 of file app_minivm.c.
References ARRAY_LEN, ast_app_separate_args, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), minivm_account::domain, LOG_ERROR, mailbox, and queue_mwi_event().
Referenced by load_module().
02044 { 02045 int argc; 02046 char *argv[4]; 02047 int res = 0; 02048 char *tmpptr; 02049 char tmp[PATH_MAX]; 02050 char *mailbox; 02051 char *domain; 02052 if (ast_strlen_zero(data)) { 02053 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 02054 return -1; 02055 } 02056 tmpptr = ast_strdupa((char *)data); 02057 if (!tmpptr) { 02058 ast_log(LOG_ERROR, "Out of memory\n"); 02059 return -1; 02060 } 02061 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02062 if (argc < 4) { 02063 ast_log(LOG_ERROR, "%d arguments passed to MiniVM_MWI, need 4.\n", argc); 02064 return -1; 02065 } 02066 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02067 mailbox = tmp; 02068 domain = strchr(tmp, '@'); 02069 if (domain) { 02070 *domain = '\0'; 02071 domain++; 02072 } 02073 if (ast_strlen_zero(domain) || ast_strlen_zero(mailbox)) { 02074 ast_log(LOG_ERROR, "Need mailbox@context as argument. Sorry. Argument 0 %s\n", argv[0]); 02075 return -1; 02076 } 02077 queue_mwi_event(mailbox, domain, atoi(argv[1]), atoi(argv[2]), atoi(argv[3])); 02078 02079 return res; 02080 }
static int minivm_notify_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 2085 of file app_minivm.c.
References ARRAY_LEN, ast_app_separate_args, ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, minivm_account::domain, find_account(), format, free_user(), LOG_ERROR, LOG_WARNING, MVM_ALLOCED, notify_new_message(), pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), S_COR, TRUE, and minivm_account::username.
Referenced by load_module().
02086 { 02087 int argc; 02088 char *argv[2]; 02089 int res = 0; 02090 char tmp[PATH_MAX]; 02091 char *domain; 02092 char *tmpptr; 02093 struct minivm_account *vmu; 02094 char *username; 02095 const char *template = ""; 02096 const char *filename; 02097 const char *format; 02098 const char *duration_string; 02099 02100 if (ast_strlen_zero(data)) { 02101 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 02102 return -1; 02103 } 02104 tmpptr = ast_strdupa((char *)data); 02105 if (!tmpptr) { 02106 ast_log(LOG_ERROR, "Out of memory\n"); 02107 return -1; 02108 } 02109 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02110 02111 if (argc == 2 && !ast_strlen_zero(argv[1])) 02112 template = argv[1]; 02113 02114 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02115 username = tmp; 02116 domain = strchr(tmp, '@'); 02117 if (domain) { 02118 *domain = '\0'; 02119 domain++; 02120 } 02121 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 02122 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]); 02123 return -1; 02124 } 02125 02126 if(!(vmu = find_account(domain, username, TRUE))) { 02127 /* We could not find user, let's exit */ 02128 ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain); 02129 pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", "FAILED"); 02130 return -1; 02131 } 02132 02133 ast_channel_lock(chan); 02134 if ((filename = pbx_builtin_getvar_helper(chan, "MVM_FILENAME"))) { 02135 filename = ast_strdupa(filename); 02136 } 02137 ast_channel_unlock(chan); 02138 /* Notify of new message to e-mail and pager */ 02139 if (!ast_strlen_zero(filename)) { 02140 ast_channel_lock(chan); 02141 if ((format = pbx_builtin_getvar_helper(chan, "MVM_FORMAT"))) { 02142 format = ast_strdupa(format); 02143 } 02144 if ((duration_string = pbx_builtin_getvar_helper(chan, "MVM_DURATION"))) { 02145 duration_string = ast_strdupa(duration_string); 02146 } 02147 ast_channel_unlock(chan); 02148 res = notify_new_message(chan, template, vmu, filename, atoi(duration_string), 02149 format, 02150 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 02151 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)); 02152 } 02153 02154 pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", res == 0 ? "SUCCESS" : "FAILED"); 02155 02156 02157 if(ast_test_flag(vmu, MVM_ALLOCED)) 02158 free_user(vmu); 02159 02160 /* Ok, we're ready to rock and roll. Return to dialplan */ 02161 02162 return res; 02163 02164 }
static int minivm_record_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 2168 of file app_minivm.c.
References ast_channel::_state, ARRAY_LEN, ast_answer(), ast_app_parse_options(), ast_app_separate_args, ast_copy_flags, ast_log(), AST_STATE_UP, ast_strdupa, ast_strlen_zero(), ast_test_flag, ERROR_LOCK_PATH, minivm_account::flags, leave_voicemail(), LOG_ERROR, LOG_WARNING, minivm_app_options, OPT_ARG_ARRAY_SIZE, OPT_ARG_RECORDGAIN, OPT_BUSY_GREETING, OPT_RECORDGAIN, OPT_SILENT, OPT_UNAVAIL_GREETING, and pbx_builtin_setvar_helper().
Referenced by load_module().
02169 { 02170 int res = 0; 02171 char *tmp; 02172 struct leave_vm_options leave_options; 02173 int argc; 02174 char *argv[2]; 02175 struct ast_flags flags = { 0 }; 02176 char *opts[OPT_ARG_ARRAY_SIZE]; 02177 02178 memset(&leave_options, 0, sizeof(leave_options)); 02179 02180 /* Answer channel if it's not already answered */ 02181 if (chan->_state != AST_STATE_UP) 02182 ast_answer(chan); 02183 02184 if (ast_strlen_zero(data)) { 02185 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 02186 return -1; 02187 } 02188 tmp = ast_strdupa((char *)data); 02189 if (!tmp) { 02190 ast_log(LOG_ERROR, "Out of memory\n"); 02191 return -1; 02192 } 02193 argc = ast_app_separate_args(tmp, ',', argv, ARRAY_LEN(argv)); 02194 if (argc == 2) { 02195 if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) { 02196 return -1; 02197 } 02198 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING ); 02199 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 02200 int gain; 02201 02202 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 02203 ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 02204 return -1; 02205 } else 02206 leave_options.record_gain = (signed char) gain; 02207 } 02208 } 02209 02210 /* Now run the appliation and good luck to you! */ 02211 res = leave_voicemail(chan, argv[0], &leave_options); 02212 02213 if (res == ERROR_LOCK_PATH) { 02214 ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 02215 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 02216 res = 0; 02217 } 02218 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS"); 02219 02220 return res; 02221 }
static struct minivm_account* mvm_user_alloc | ( | void | ) | [static] |
Definition at line 1025 of file app_minivm.c.
References ast_calloc, and populate_defaults().
Referenced by find_account(), and find_user_realtime().
01026 { 01027 struct minivm_account *new; 01028 01029 new = ast_calloc(1, sizeof(*new)); 01030 if (!new) 01031 return NULL; 01032 populate_defaults(new); 01033 01034 return new; 01035 }
static int notify_new_message | ( | struct ast_channel * | chan, | |
const char * | templatename, | |||
struct minivm_account * | vmu, | |||
const char * | filename, | |||
long | duration, | |||
const char * | format, | |||
char * | cidnum, | |||
char * | cidname | |||
) | [static] |
Definition at line 1766 of file app_minivm.c.
References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_log(), ast_manager_event, ast_strdupa, ast_strlen_zero(), minivm_account::attachfmt, minivm_account::domain, minivm_account::etemplate, EVENT_FLAG_CALL, LOG_WARNING, message_template_find(), MVM_MESSAGE_EMAIL, minivm_account::pager, pbx_builtin_getvar_helper(), minivm_account::ptemplate, run_externnotify(), sendmail(), strsep(), and minivm_account::username.
Referenced by copy_message(), and minivm_notify_exec().
01767 { 01768 char *stringp; 01769 struct minivm_template *etemplate; 01770 char *messageformat; 01771 int res = 0; 01772 char oldlocale[100]; 01773 const char *counter; 01774 01775 if (!ast_strlen_zero(vmu->attachfmt)) { 01776 if (strstr(format, vmu->attachfmt)) { 01777 format = vmu->attachfmt; 01778 } else { 01779 ast_log(LOG_WARNING, "Attachment format '%s' is not one of the recorded formats '%s'. Falling back to default format for '%s@%s'.\n", vmu->attachfmt, format, vmu->username, vmu->domain); 01780 } 01781 } 01782 01783 etemplate = message_template_find(vmu->etemplate); 01784 if (!etemplate) 01785 etemplate = message_template_find(templatename); 01786 if (!etemplate) 01787 etemplate = message_template_find("email-default"); 01788 01789 /* Attach only the first format */ 01790 stringp = messageformat = ast_strdupa(format); 01791 strsep(&stringp, "|"); 01792 01793 if (!ast_strlen_zero(etemplate->locale)) { 01794 char *new_locale; 01795 ast_copy_string(oldlocale, setlocale(LC_TIME, NULL), sizeof(oldlocale)); 01796 ast_debug(2, "Changing locale from %s to %s\n", oldlocale, etemplate->locale); 01797 new_locale = setlocale(LC_TIME, etemplate->locale); 01798 if (new_locale == NULL) { 01799 ast_log(LOG_WARNING, "-_-_- Changing to new locale did not work. Locale: %s\n", etemplate->locale); 01800 } 01801 } 01802 01803 01804 01805 /* Read counter if available */ 01806 ast_channel_lock(chan); 01807 if ((counter = pbx_builtin_getvar_helper(chan, "MVM_COUNTER"))) { 01808 counter = ast_strdupa(counter); 01809 } 01810 ast_channel_unlock(chan); 01811 01812 if (ast_strlen_zero(counter)) { 01813 ast_debug(2, "MVM_COUNTER not found\n"); 01814 } else { 01815 ast_debug(2, "MVM_COUNTER found - will use it with value %s\n", counter); 01816 } 01817 01818 res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_EMAIL, counter); 01819 01820 if (res == 0 && !ast_strlen_zero(vmu->pager)) { 01821 /* Find template for paging */ 01822 etemplate = message_template_find(vmu->ptemplate); 01823 if (!etemplate) 01824 etemplate = message_template_find("pager-default"); 01825 if (etemplate->locale) { 01826 ast_copy_string(oldlocale, setlocale(LC_TIME, ""), sizeof(oldlocale)); 01827 setlocale(LC_TIME, etemplate->locale); 01828 } 01829 01830 res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_PAGE, counter); 01831 } 01832 01833 ast_manager_event(chan, EVENT_FLAG_CALL, "MiniVoiceMail", "Action: SentNotification\rn\nMailbox: %s@%s\r\nCounter: %s\r\n", vmu->username, vmu->domain, counter); 01834 01835 run_externnotify(chan, vmu); /* Run external notification */ 01836 01837 if (etemplate->locale) { 01838 setlocale(LC_TIME, oldlocale); /* Rest to old locale */ 01839 } 01840 return res; 01841 }
static int play_record_review | ( | struct ast_channel * | chan, | |
char * | playfile, | |||
char * | recordfile, | |||
int | maxtime, | |||
char * | fmt, | |||
int | outsidecaller, | |||
struct minivm_account * | vmu, | |||
int * | duration, | |||
int * | sound_duration, | |||
const char * | unlockdir, | |||
signed char | record_gain | |||
) | [static] |
Definition at line 1613 of file app_minivm.c.
References acceptdtmf, ast_channel_setoption(), AST_DIGIT_ANY, ast_log(), AST_OPTION_RXGAIN, ast_play_and_record_full(), ast_play_and_wait(), ast_stream_and_wait(), ast_streamfile(), ast_test_flag, ast_verb, ast_waitfordigit(), ast_waitstream(), global_maxsilence, global_silencethreshold, ast_channel::language, LOG_WARNING, MVM_OPERATOR, MVM_REVIEW, and vm_delete().
Referenced by leave_voicemail(), minivm_accmess_exec(), vm_forwardoptions(), vm_newuser(), vm_options(), and vm_tempgreeting().
01616 { 01617 int cmd = 0; 01618 int max_attempts = 3; 01619 int attempts = 0; 01620 int recorded = 0; 01621 int message_exists = 0; 01622 signed char zero_gain = 0; 01623 char *acceptdtmf = "#"; 01624 char *canceldtmf = ""; 01625 01626 /* Note that urgent and private are for flagging messages as such in the future */ 01627 01628 /* barf if no pointer passed to store duration in */ 01629 if (duration == NULL) { 01630 ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n"); 01631 return -1; 01632 } 01633 01634 cmd = '3'; /* Want to start by recording */ 01635 01636 while ((cmd >= 0) && (cmd != 't')) { 01637 switch (cmd) { 01638 case '1': 01639 ast_verb(3, "Saving message as is\n"); 01640 ast_stream_and_wait(chan, "vm-msgsaved", ""); 01641 cmd = 't'; 01642 break; 01643 case '2': 01644 /* Review */ 01645 ast_verb(3, "Reviewing the message\n"); 01646 ast_streamfile(chan, recordfile, chan->language); 01647 cmd = ast_waitstream(chan, AST_DIGIT_ANY); 01648 break; 01649 case '3': 01650 message_exists = 0; 01651 /* Record */ 01652 if (recorded == 1) 01653 ast_verb(3, "Re-recording the message\n"); 01654 else 01655 ast_verb(3, "Recording the message\n"); 01656 if (recorded && outsidecaller) 01657 cmd = ast_play_and_wait(chan, "beep"); 01658 recorded = 1; 01659 /* After an attempt has been made to record message, we have to take care of INTRO and beep for incoming messages, but not for greetings */ 01660 if (record_gain) 01661 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 01662 if (ast_test_flag(vmu, MVM_OPERATOR)) 01663 canceldtmf = "0"; 01664 cmd = ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, global_silencethreshold, global_maxsilence, unlockdir, acceptdtmf, canceldtmf); 01665 if (record_gain) 01666 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 01667 if (cmd == -1) /* User has hung up, no options to give */ 01668 return cmd; 01669 if (cmd == '0') 01670 break; 01671 else if (cmd == '*') 01672 break; 01673 else { 01674 /* If all is well, a message exists */ 01675 message_exists = 1; 01676 cmd = 0; 01677 } 01678 break; 01679 case '4': 01680 case '5': 01681 case '6': 01682 case '7': 01683 case '8': 01684 case '9': 01685 case '*': 01686 case '#': 01687 cmd = ast_play_and_wait(chan, "vm-sorry"); 01688 break; 01689 case '0': 01690 if(!ast_test_flag(vmu, MVM_OPERATOR)) { 01691 cmd = ast_play_and_wait(chan, "vm-sorry"); 01692 break; 01693 } 01694 if (message_exists || recorded) { 01695 cmd = ast_play_and_wait(chan, "vm-saveoper"); 01696 if (!cmd) 01697 cmd = ast_waitfordigit(chan, 3000); 01698 if (cmd == '1') { 01699 ast_play_and_wait(chan, "vm-msgsaved"); 01700 cmd = '0'; 01701 } else { 01702 ast_play_and_wait(chan, "vm-deleted"); 01703 vm_delete(recordfile); 01704 cmd = '0'; 01705 } 01706 } 01707 return cmd; 01708 default: 01709 /* If the caller is an ouside caller, and the review option is enabled, 01710 allow them to review the message, but let the owner of the box review 01711 their OGM's */ 01712 if (outsidecaller && !ast_test_flag(vmu, MVM_REVIEW)) 01713 return cmd; 01714 if (message_exists) { 01715 cmd = ast_play_and_wait(chan, "vm-review"); 01716 } else { 01717 cmd = ast_play_and_wait(chan, "vm-torerecord"); 01718 if (!cmd) 01719 cmd = ast_waitfordigit(chan, 600); 01720 } 01721 01722 if (!cmd && outsidecaller && ast_test_flag(vmu, MVM_OPERATOR)) { 01723 cmd = ast_play_and_wait(chan, "vm-reachoper"); 01724 if (!cmd) 01725 cmd = ast_waitfordigit(chan, 600); 01726 } 01727 if (!cmd) 01728 cmd = ast_waitfordigit(chan, 6000); 01729 if (!cmd) { 01730 attempts++; 01731 } 01732 if (attempts > max_attempts) { 01733 cmd = 't'; 01734 } 01735 } 01736 } 01737 if (outsidecaller) 01738 ast_play_and_wait(chan, "vm-goodbye"); 01739 if (cmd == 't') 01740 cmd = 0; 01741 return cmd; 01742 }
static void populate_defaults | ( | struct minivm_account * | vmu | ) | [static] |
Definition at line 1016 of file app_minivm.c.
References ast_copy_flags, ast_copy_string(), AST_FLAGS_ALL, minivm_account::attachfmt, default_vmformat, global_volgain, globalflags, and minivm_account::volgain.
Referenced by actual_load_config(), append_mailbox(), AST_TEST_DEFINE(), create_vmaccount(), find_user_realtime(), and mvm_user_alloc().
01017 { 01018 ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL); 01019 ast_copy_string(vmu->attachfmt, default_vmformat, sizeof(vmu->attachfmt)); 01020 vmu->volgain = global_volgain; 01021 }
static void prep_email_sub_vars | ( | struct ast_channel * | channel, | |
const struct minivm_account * | vmu, | |||
const char * | cidnum, | |||
const char * | cidname, | |||
const char * | dur, | |||
const char * | date, | |||
const char * | counter | |||
) | [static] |
Definition at line 987 of file app_minivm.c.
References ast_callerid_merge(), ast_log(), ast_strlen_zero(), minivm_account::chanvars, minivm_account::domain, minivm_account::fullname, LOG_ERROR, pbx_builtin_setvar_helper(), minivm_account::username, and var.
Referenced by make_email_file(), sendmail(), and sendpage().
00988 { 00989 char callerid[256]; 00990 struct ast_variable *var; 00991 00992 if (!channel) { 00993 ast_log(LOG_ERROR, "No allocated channel, giving up...\n"); 00994 return; 00995 } 00996 00997 for (var = vmu->chanvars ; var ; var = var->next) { 00998 pbx_builtin_setvar_helper(channel, var->name, var->value); 00999 } 01000 01001 /* Prepare variables for substition in email body and subject */ 01002 pbx_builtin_setvar_helper(channel, "MVM_NAME", vmu->fullname); 01003 pbx_builtin_setvar_helper(channel, "MVM_DUR", dur); 01004 pbx_builtin_setvar_helper(channel, "MVM_DOMAIN", vmu->domain); 01005 pbx_builtin_setvar_helper(channel, "MVM_USERNAME", vmu->username); 01006 pbx_builtin_setvar_helper(channel, "MVM_CALLERID", ast_callerid_merge(callerid, sizeof(callerid), cidname, cidnum, "Unknown Caller")); 01007 pbx_builtin_setvar_helper(channel, "MVM_CIDNAME", (cidname ? cidname : "an unknown caller")); 01008 pbx_builtin_setvar_helper(channel, "MVM_CIDNUM", (cidnum ? cidnum : "an unknown caller")); 01009 pbx_builtin_setvar_helper(channel, "MVM_DATE", date); 01010 if (!ast_strlen_zero(counter)) 01011 pbx_builtin_setvar_helper(channel, "MVM_COUNTER", counter); 01012 }
static void queue_mwi_event | ( | const char * | mbx, | |
const char * | ctx, | |||
int | urgent, | |||
int | new, | |||
int | old | |||
) | [static] |
Definition at line 2018 of file app_minivm.c.
References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_IE_PLTYPE_UINT, AST_EVENT_MWI, ast_event_new(), ast_event_queue_and_cache(), ast_strdupa, ast_strlen_zero(), context, and mailbox.
Referenced by append_mailbox(), minivm_mwi_exec(), notify_new_message(), poll_subscribed_mailbox(), and vm_execmain().
02019 { 02020 struct ast_event *event; 02021 char *mailbox, *context; 02022 02023 mailbox = ast_strdupa(mbx); 02024 context = ast_strdupa(ctx); 02025 if (ast_strlen_zero(context)) { 02026 context = "default"; 02027 } 02028 02029 if (!(event = ast_event_new(AST_EVENT_MWI, 02030 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 02031 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 02032 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 02033 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 02034 AST_EVENT_IE_END))) { 02035 return; 02036 } 02037 02038 ast_event_queue_and_cache(event); 02039 }
static int reload | ( | void | ) | [static] |
Reload mini voicemail module.
Definition at line 3529 of file app_minivm.c.
References load_config().
03530 { 03531 return(load_config(1)); 03532 }
static void run_externnotify | ( | struct ast_channel * | chan, | |
struct minivm_account * | vmu | |||
) | [static] |
Run external notification for voicemail message.
Definition at line 1745 of file app_minivm.c.
References ast_debug, ast_safe_system(), ast_strlen_zero(), ast_channel::caller, minivm_account::domain, minivm_account::externnotify, global_externnotify, ast_party_caller::id, ast_party_id::name, ast_party_id::number, ast_party_number::str, ast_party_name::str, minivm_account::username, ast_party_number::valid, and ast_party_name::valid.
Referenced by forward_message(), notify_new_message(), poll_subscribed_mailbox(), and vm_execmain().
01746 { 01747 char arguments[BUFSIZ]; 01748 01749 if (ast_strlen_zero(vmu->externnotify) && ast_strlen_zero(global_externnotify)) 01750 return; 01751 01752 snprintf(arguments, sizeof(arguments), "%s %s@%s %s %s&", 01753 ast_strlen_zero(vmu->externnotify) ? global_externnotify : vmu->externnotify, 01754 vmu->username, vmu->domain, 01755 (chan->caller.id.name.valid && chan->caller.id.name.str) 01756 ? chan->caller.id.name.str : "", 01757 (chan->caller.id.number.valid && chan->caller.id.number.str) 01758 ? chan->caller.id.number.str : ""); 01759 01760 ast_debug(1, "Executing: %s\n", arguments); 01761 ast_safe_system(arguments); 01762 }
static int sendmail | ( | struct minivm_template * | template, | |
struct minivm_account * | vmu, | |||
char * | cidnum, | |||
char * | cidname, | |||
const char * | filename, | |||
char * | format, | |||
int | duration, | |||
int | attach_user_voicemail, | |||
enum mvm_messagetype | type, | |||
const char * | counter | |||
) | [static] |
Definition at line 1220 of file app_minivm.c.
References ast_channel_unref, ast_copy_string(), ast_debug, ast_dummy_channel_alloc(), ast_free, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_localtime(), ast_log(), ast_random(), ast_safe_system(), ast_str_buffer(), ast_str_create(), ast_str_encode_mime(), ast_str_quote(), ast_str_set(), ast_str_substitute_variables(), ast_strdupa, ast_strftime(), ast_strlen_zero(), ast_tvnow(), minivm_template::attachment, base_encode(), minivm_template::body, minivm_template::charset, check_mime(), minivm_template::dateformat, minivm_account::domain, minivm_account::email, minivm_template::fromaddress, minivm_account::fullname, global_mailcmd, minivm_account::list, LOG_WARNING, MAXHOSTNAMELEN, MVM_MESSAGE_EMAIL, minivm_zone::name, minivm_template::name, option_debug, minivm_account::pager, prep_email_sub_vars(), minivm_account::serveremail, minivm_template::subject, minivm_zone::timezone, minivm_account::username, minivm_account::volgain, and minivm_account::zonetag.
Referenced by forward_message(), and notify_new_message().
01221 { 01222 FILE *p = NULL; 01223 int pfd; 01224 char email[256] = ""; 01225 char who[256] = ""; 01226 char date[256]; 01227 char bound[256]; 01228 char fname[PATH_MAX]; 01229 char dur[PATH_MAX]; 01230 char tmp[80] = "/tmp/astmail-XXXXXX"; 01231 char tmp2[PATH_MAX]; 01232 struct timeval now; 01233 struct ast_tm tm; 01234 struct minivm_zone *the_zone = NULL; 01235 struct ast_channel *ast; 01236 char *finalfilename = ""; 01237 struct ast_str *str1 = ast_str_create(16), *str2 = ast_str_create(16); 01238 char *fromaddress; 01239 char *fromemail; 01240 01241 if (!str1 || !str2) { 01242 ast_free(str1); 01243 ast_free(str2); 01244 return -1; 01245 } 01246 01247 if (type == MVM_MESSAGE_EMAIL) { 01248 if (vmu && !ast_strlen_zero(vmu->email)) { 01249 ast_copy_string(email, vmu->email, sizeof(email)); 01250 } else if (!ast_strlen_zero(vmu->username) && !ast_strlen_zero(vmu->domain)) 01251 snprintf(email, sizeof(email), "%s@%s", vmu->username, vmu->domain); 01252 } else if (type == MVM_MESSAGE_PAGE) { 01253 ast_copy_string(email, vmu->pager, sizeof(email)); 01254 } 01255 01256 if (ast_strlen_zero(email)) { 01257 ast_log(LOG_WARNING, "No address to send message to.\n"); 01258 ast_free(str1); 01259 ast_free(str2); 01260 return -1; 01261 } 01262 01263 ast_debug(3, "Sending mail to %s@%s - Using template %s\n", vmu->username, vmu->domain, template->name); 01264 01265 if (!strcmp(format, "wav49")) 01266 format = "WAV"; 01267 01268 01269 /* If we have a gain option, process it now with sox */ 01270 if (type == MVM_MESSAGE_EMAIL && (vmu->volgain < -.001 || vmu->volgain > .001) ) { 01271 char newtmp[PATH_MAX]; 01272 char tmpcmd[PATH_MAX]; 01273 int tmpfd; 01274 01275 /** 01276 * XXX 01277 * /bug tmpfd is a leaked fd. The file is also never unlinked. 01278 * See app_voicemail.c for how the code works there that 01279 * doesn't have this bug. 01280 */ 01281 01282 ast_copy_string(newtmp, "/tmp/XXXXXX", sizeof(newtmp)); 01283 ast_debug(3, "newtmp: %s\n", newtmp); 01284 tmpfd = mkstemp(newtmp); 01285 if (tmpfd > -1) { 01286 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, filename, format, newtmp, format); 01287 ast_safe_system(tmpcmd); 01288 finalfilename = newtmp; 01289 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", filename, format, vmu->volgain, vmu->username); 01290 } 01291 } else { 01292 finalfilename = ast_strdupa(filename); 01293 } 01294 01295 /* Create file name */ 01296 snprintf(fname, sizeof(fname), "%s.%s", finalfilename, format); 01297 01298 if (template->attachment) 01299 ast_debug(1, "Attaching file '%s', format '%s', uservm is '%d'\n", finalfilename, format, attach_user_voicemail); 01300 01301 /* Make a temporary file instead of piping directly to sendmail, in case the mail 01302 command hangs */ 01303 pfd = mkstemp(tmp); 01304 if (pfd > -1) { 01305 p = fdopen(pfd, "w"); 01306 if (!p) { 01307 close(pfd); 01308 pfd = -1; 01309 } 01310 ast_debug(1, "Opening temp file for e-mail: %s\n", tmp); 01311 } 01312 if (!p) { 01313 ast_log(LOG_WARNING, "Unable to open temporary file '%s'\n", tmp); 01314 ast_free(str1); 01315 ast_free(str2); 01316 return -1; 01317 } 01318 /* Allocate channel used for chanvar substitution */ 01319 ast = ast_dummy_channel_alloc(); 01320 if (!ast) { 01321 ast_free(str1); 01322 ast_free(str2); 01323 return -1; 01324 } 01325 01326 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 01327 01328 /* Does this user have a timezone specified? */ 01329 if (!ast_strlen_zero(vmu->zonetag)) { 01330 /* Find the zone in the list */ 01331 struct minivm_zone *z; 01332 AST_LIST_LOCK(&minivm_zones); 01333 AST_LIST_TRAVERSE(&minivm_zones, z, list) { 01334 if (strcmp(z->name, vmu->zonetag)) 01335 continue; 01336 the_zone = z; 01337 } 01338 AST_LIST_UNLOCK(&minivm_zones); 01339 } 01340 01341 now = ast_tvnow(); 01342 ast_localtime(&now, &tm, the_zone ? the_zone->timezone : NULL); 01343 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", &tm); 01344 01345 /* Start printing the email to the temporary file */ 01346 fprintf(p, "Date: %s\n", date); 01347 01348 /* Set date format for voicemail mail */ 01349 ast_strftime(date, sizeof(date), template->dateformat, &tm); 01350 01351 01352 /* Populate channel with channel variables for substitution */ 01353 prep_email_sub_vars(ast, vmu, cidnum, cidname, dur, date, counter); 01354 01355 /* Find email address to use */ 01356 /* If there's a server e-mail adress in the account, user that, othterwise template */ 01357 fromemail = ast_strlen_zero(vmu->serveremail) ? template->serveremail : vmu->serveremail; 01358 01359 /* Find name to user for server e-mail */ 01360 fromaddress = ast_strlen_zero(template->fromaddress) ? "" : template->fromaddress; 01361 01362 /* If needed, add hostname as domain */ 01363 if (ast_strlen_zero(fromemail)) 01364 fromemail = "asterisk"; 01365 01366 if (strchr(fromemail, '@')) 01367 ast_copy_string(who, fromemail, sizeof(who)); 01368 else { 01369 char host[MAXHOSTNAMELEN]; 01370 gethostname(host, sizeof(host)-1); 01371 snprintf(who, sizeof(who), "%s@%s", fromemail, host); 01372 } 01373 01374 if (ast_strlen_zero(fromaddress)) { 01375 fprintf(p, "From: Asterisk PBX <%s>\n", who); 01376 } else { 01377 ast_debug(4, "Fromaddress template: %s\n", fromaddress); 01378 ast_str_substitute_variables(&str1, 0, ast, fromaddress); 01379 if (check_mime(ast_str_buffer(str1))) { 01380 int first_line = 1; 01381 char *ptr; 01382 ast_str_encode_mime(&str2, 0, template->charset, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 01383 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 01384 *ptr = '\0'; 01385 fprintf(p, "%s %s\n", first_line ? "From:" : "", ast_str_buffer(str2)); 01386 first_line = 0; 01387 /* Substring is smaller, so this will never grow */ 01388 ast_str_set(&str2, 0, "%s", ptr + 1); 01389 } 01390 fprintf(p, "%s %s <%s>\n", first_line ? "From:" : "", ast_str_buffer(str2), who); 01391 } else { 01392 fprintf(p, "From: %s <%s>\n", ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 01393 } 01394 } 01395 01396 fprintf(p, "Message-ID: <Asterisk-%d-%s-%d-%s>\n", (unsigned int)ast_random(), vmu->username, (int)getpid(), who); 01397 01398 if (ast_strlen_zero(vmu->email)) { 01399 snprintf(email, sizeof(email), "%s@%s", vmu->username, vmu->domain); 01400 } else { 01401 ast_copy_string(email, vmu->email, sizeof(email)); 01402 } 01403 01404 if (check_mime(vmu->fullname)) { 01405 int first_line = 1; 01406 char *ptr; 01407 ast_str_encode_mime(&str2, 0, template->charset, vmu->fullname, strlen("To: "), strlen(email) + 3); 01408 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 01409 *ptr = '\0'; 01410 fprintf(p, "%s %s\n", first_line ? "To:" : "", ast_str_buffer(str2)); 01411 first_line = 0; 01412 /* Substring is smaller, so this will never grow */ 01413 ast_str_set(&str2, 0, "%s", ptr + 1); 01414 } 01415 fprintf(p, "%s %s <%s>\n", first_line ? "To:" : "", ast_str_buffer(str2), email); 01416 } else { 01417 fprintf(p, "To: %s <%s>\n", ast_str_quote(&str2, 0, vmu->fullname), email); 01418 } 01419 01420 if (!ast_strlen_zero(template->subject)) { 01421 ast_str_substitute_variables(&str1, 0, ast, template->subject); 01422 if (check_mime(ast_str_buffer(str1))) { 01423 int first_line = 1; 01424 char *ptr; 01425 ast_str_encode_mime(&str2, 0, template->charset, ast_str_buffer(str1), strlen("Subject: "), 0); 01426 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 01427 *ptr = '\0'; 01428 fprintf(p, "%s %s\n", first_line ? "Subject:" : "", ast_str_buffer(str2)); 01429 first_line = 0; 01430 /* Substring is smaller, so this will never grow */ 01431 ast_str_set(&str2, 0, "%s", ptr + 1); 01432 } 01433 fprintf(p, "%s %s\n", first_line ? "Subject:" : "", ast_str_buffer(str2)); 01434 } else { 01435 fprintf(p, "Subject: %s\n", ast_str_buffer(str1)); 01436 } 01437 } else { 01438 fprintf(p, "Subject: New message in mailbox %s@%s\n", vmu->username, vmu->domain); 01439 ast_debug(1, "Using default subject for this email \n"); 01440 } 01441 01442 if (option_debug > 2) 01443 fprintf(p, "X-Asterisk-debug: template %s user account %s@%s\n", template->name, vmu->username, vmu->domain); 01444 fprintf(p, "MIME-Version: 1.0\n"); 01445 01446 /* Something unique. */ 01447 snprintf(bound, sizeof(bound), "voicemail_%s%d%d", vmu->username, (int)getpid(), (unsigned int)ast_random()); 01448 01449 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"\n\n\n", bound); 01450 01451 fprintf(p, "--%s\n", bound); 01452 fprintf(p, "Content-Type: text/plain; charset=%s\nContent-Transfer-Encoding: 8bit\n\n", template->charset); 01453 if (!ast_strlen_zero(template->body)) { 01454 ast_str_substitute_variables(&str1, 0, ast, template->body); 01455 ast_debug(3, "Message now: %s\n-----\n", ast_str_buffer(str1)); 01456 fprintf(p, "%s\n", ast_str_buffer(str1)); 01457 } else { 01458 fprintf(p, "Dear %s:\n\n\tJust wanted to let you know you were just left a %s long message \n" 01459 "in mailbox %s from %s, on %s so you might\n" 01460 "want to check it when you get a chance. Thanks!\n\n\t\t\t\t--Asterisk\n\n", vmu->fullname, 01461 dur, vmu->username, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 01462 ast_debug(3, "Using default message body (no template)\n-----\n"); 01463 } 01464 /* Eww. We want formats to tell us their own MIME type */ 01465 if (template->attachment) { 01466 char *ctype = "audio/x-"; 01467 ast_debug(3, "Attaching file to message: %s\n", fname); 01468 if (!strcasecmp(format, "ogg")) 01469 ctype = "application/"; 01470 01471 fprintf(p, "--%s\n", bound); 01472 fprintf(p, "Content-Type: %s%s; name=\"voicemailmsg.%s\"\n", ctype, format, format); 01473 fprintf(p, "Content-Transfer-Encoding: base64\n"); 01474 fprintf(p, "Content-Description: Voicemail sound attachment.\n"); 01475 fprintf(p, "Content-Disposition: attachment; filename=\"voicemail%s.%s\"\n\n", counter ? counter : "", format); 01476 01477 base_encode(fname, p); 01478 fprintf(p, "\n\n--%s--\n.\n", bound); 01479 } 01480 fclose(p); 01481 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", global_mailcmd, tmp, tmp); 01482 ast_safe_system(tmp2); 01483 ast_debug(1, "Sent message to %s with command '%s' - %s\n", vmu->email, global_mailcmd, template->attachment ? "(media attachment)" : ""); 01484 ast_debug(3, "Actual command used: %s\n", tmp2); 01485 ast = ast_channel_unref(ast); 01486 ast_free(str1); 01487 ast_free(str2); 01488 return 0; 01489 }
static int timezone_add | ( | const char * | zonename, | |
const char * | config | |||
) | [static] |
Add time zone to memory list.
Definition at line 2674 of file app_minivm.c.
References ast_calloc, ast_copy_string(), ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strdupa, global_stats, minivm_account::list, LOG_WARNING, strsep(), and minivm_stats::timezones.
Referenced by load_config().
02675 { 02676 struct minivm_zone *newzone; 02677 char *msg_format, *timezone_str; 02678 02679 newzone = ast_calloc(1, sizeof(*newzone)); 02680 if (newzone == NULL) 02681 return 0; 02682 02683 msg_format = ast_strdupa(config); 02684 if (msg_format == NULL) { 02685 ast_log(LOG_WARNING, "Out of memory.\n"); 02686 ast_free(newzone); 02687 return 0; 02688 } 02689 02690 timezone_str = strsep(&msg_format, "|"); 02691 if (!msg_format) { 02692 ast_log(LOG_WARNING, "Invalid timezone definition : %s\n", zonename); 02693 ast_free(newzone); 02694 return 0; 02695 } 02696 02697 ast_copy_string(newzone->name, zonename, sizeof(newzone->name)); 02698 ast_copy_string(newzone->timezone, timezone_str, sizeof(newzone->timezone)); 02699 ast_copy_string(newzone->msg_format, msg_format, sizeof(newzone->msg_format)); 02700 02701 AST_LIST_LOCK(&minivm_zones); 02702 AST_LIST_INSERT_TAIL(&minivm_zones, newzone, list); 02703 AST_LIST_UNLOCK(&minivm_zones); 02704 02705 global_stats.timezones++; 02706 02707 return 0; 02708 }
static void timezone_destroy_list | ( | void | ) | [static] |
Clear list of timezones.
Definition at line 2662 of file app_minivm.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, free_zone(), and minivm_account::list.
Referenced by load_config(), and unload_module().
02663 { 02664 struct minivm_zone *this; 02665 02666 AST_LIST_LOCK(&minivm_zones); 02667 while ((this = AST_LIST_REMOVE_HEAD(&minivm_zones, list))) 02668 free_zone(this); 02669 02670 AST_LIST_UNLOCK(&minivm_zones); 02671 }
static int unload_module | ( | void | ) | [static] |
Unload mini voicemail module.
Definition at line 3555 of file app_minivm.c.
References ARRAY_LEN, ast_cli_unregister_multiple(), ast_custom_function_unregister(), ast_unregister_application(), cli_minivm, message_destroy_list(), minivm_account_function, minivm_counter_function, timezone_destroy_list(), and vmaccounts_destroy_list().
03556 { 03557 int res; 03558 03559 res = ast_unregister_application(app_minivm_record); 03560 res |= ast_unregister_application(app_minivm_greet); 03561 res |= ast_unregister_application(app_minivm_notify); 03562 res |= ast_unregister_application(app_minivm_delete); 03563 res |= ast_unregister_application(app_minivm_accmess); 03564 res |= ast_unregister_application(app_minivm_mwi); 03565 03566 ast_cli_unregister_multiple(cli_minivm, ARRAY_LEN(cli_minivm)); 03567 ast_custom_function_unregister(&minivm_account_function); 03568 ast_custom_function_unregister(&minivm_counter_function); 03569 03570 message_destroy_list(); /* Destroy list of voicemail message templates */ 03571 timezone_destroy_list(); /* Destroy list of timezones */ 03572 vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */ 03573 03574 return res; 03575 }
static int vm_delete | ( | char * | file | ) | [static] |
Definition at line 1599 of file app_minivm.c.
References ast_debug, and ast_filedelete().
Referenced by copy_message(), minivm_delete_exec(), notify_new_message(), and play_record_review().
01600 { 01601 int res; 01602 01603 ast_debug(1, "Deleting voicemail file %s\n", file); 01604 01605 res = unlink(file); /* Remove the meta data file */ 01606 res |= ast_filedelete(file, NULL); /* remove the media file */ 01607 return res; 01608 }
static int vm_lock_path | ( | const char * | path | ) | [static] |
lock directory
only return failure if ast_lock_path returns 'timeout', not if the path does not exist or any other reason
Definition at line 3279 of file app_minivm.c.
References ast_lock_path(), and AST_LOCK_TIMEOUT.
Referenced by access_counter_file(), close_mailbox(), copy_message(), count_messages(), open_mailbox(), resequence_mailbox(), and save_to_folder().
03280 { 03281 switch (ast_lock_path(path)) { 03282 case AST_LOCK_TIMEOUT: 03283 return -1; 03284 default: 03285 return 0; 03286 } 03287 }
static void vmaccounts_destroy_list | ( | void | ) | [static] |
Definition at line 1040 of file app_minivm.c.
References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and minivm_account::list.
Referenced by load_config(), and unload_module().
01041 { 01042 struct minivm_account *this; 01043 AST_LIST_LOCK(&minivm_accounts); 01044 while ((this = AST_LIST_REMOVE_HEAD(&minivm_accounts, list))) 01045 ast_free(this); 01046 AST_LIST_UNLOCK(&minivm_accounts); 01047 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Mini VoiceMail (A minimal Voicemail e-mail System)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 3582 of file app_minivm.c.
char* app_minivm_accmess = "MinivmAccMess" [static] |
Definition at line 550 of file app_minivm.c.
char* app_minivm_delete = "MinivmDelete" [static] |
Definition at line 549 of file app_minivm.c.
char* app_minivm_greet = "MinivmGreet" [static] |
Definition at line 547 of file app_minivm.c.
char* app_minivm_mwi = "MinivmMWI" [static] |
Definition at line 551 of file app_minivm.c.
char* app_minivm_notify = "MinivmNotify" [static] |
Definition at line 548 of file app_minivm.c.
char* app_minivm_record = "MinivmRecord" [static] |
Definition at line 546 of file app_minivm.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 3582 of file app_minivm.c.
struct ast_cli_entry cli_minivm[] [static] |
CLI commands for Mini-voicemail.
Definition at line 3480 of file app_minivm.c.
Referenced by load_module(), and unload_module().
char default_vmformat[80] [static] |
Definition at line 687 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), leave_voicemail(), load_config(), minivm_accmess_exec(), and populate_defaults().
char global_externnotify[160] [static] |
External notification application
Definition at line 685 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and run_externnotify().
char global_logfile[PATH_MAX] [static] |
Global log file for messages
Definition at line 686 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), and load_config().
char global_mailcmd[160] [static] |
Configurable mail cmd
Definition at line 684 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and sendmail().
int global_maxgreet [static] |
Maximum length of prompts
Definition at line 682 of file app_minivm.c.
Referenced by apply_general_options(), load_config(), and minivm_accmess_exec().
int global_maxsilence [static] |
Maximum silence during recording
Definition at line 681 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and play_record_review().
int global_saydurationminfo [static] |
int global_silencethreshold = 128 [static] |
Definition at line 683 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), load_config(), and play_record_review().
struct minivm_stats global_stats [static] |
Statistics for voicemail.
Definition at line 672 of file app_minivm.c.
Referenced by create_vmaccount(), handle_minivm_show_stats(), leave_voicemail(), load_config(), message_template_build(), and timezone_add().
int global_vmmaxmessage [static] |
Maximum duration of message
Definition at line 680 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), leave_voicemail(), and load_config().
int global_vmminmessage [static] |
Minimum duration of messages
Definition at line 679 of file app_minivm.c.
Referenced by apply_general_options(), handle_minivm_show_settings(), leave_voicemail(), and load_config().
double global_volgain [static] |
Volume gain for voicmemail via e-mail
Definition at line 692 of file app_minivm.c.
Referenced by populate_defaults().
struct ast_flags globalflags = {0} [static] |
Global voicemail flags
Definition at line 689 of file app_minivm.c.
Referenced by __expire_registry(), __find_callno(), actual_load_config(), aji_build_publish_skeleton(), aji_create_client(), aji_load_config(), aji_pubsub_subscribe(), apply_general_options(), build_peer(), build_user(), check_access(), find_or_create(), find_user(), find_user_realtime(), forward_message(), handle_minivm_show_settings(), iax2_request(), iax2_trunk_queue(), load_config(), make_email_file(), populate_defaults(), realtime_update_peer(), send_trunk(), sendmail(), set_config(), set_config_destroy(), socket_process(), update_registry(), and vm_execmain().
struct ast_app_option minivm_accmess_options[128] = { [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 't' ] = { .flag = OPT_TEMP_GREETING }, [ 'n' ] = { .flag = OPT_NAME_GREETING },} [static] |
struct ast_custom_function minivm_account_function [static] |
Initial value:
{ .name = "MINIVMACCOUNT", .read = minivm_account_func_read, }
Definition at line 3495 of file app_minivm.c.
Referenced by load_module(), and unload_module().
struct ast_app_option minivm_app_options[128] = { [ 's' ] = { .flag = OPT_SILENT }, [ 'b' ] = { .flag = OPT_BUSY_GREETING }, [ 'u' ] = { .flag = OPT_UNAVAIL_GREETING }, [ 'g' ] = { .flag = OPT_RECORDGAIN , .arg_index = OPT_ARG_RECORDGAIN + 1 },} [static] |
Definition at line 574 of file app_minivm.c.
Referenced by minivm_greet_exec(), and minivm_record_exec().
struct ast_custom_function minivm_counter_function [static] |
Initial value:
{ .name = "MINIVMCOUNTER", .read = minivm_counter_func_read, .write = minivm_counter_func_write, }
Definition at line 3489 of file app_minivm.c.
Referenced by load_module(), and unload_module().
ast_mutex_t minivmlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Lock to protect voicemail system
Definition at line 674 of file app_minivm.c.
Referenced by load_config().
FILE* minivmlogfile [static] |
The minivm log file
Definition at line 677 of file app_minivm.c.
Referenced by leave_voicemail(), and load_config().
ast_mutex_t minivmloglock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 } [static] |
Lock to protect voicemail system log file
Definition at line 675 of file app_minivm.c.
Referenced by leave_voicemail().
char MVM_SPOOL_DIR[PATH_MAX] [static] |
Definition at line 543 of file app_minivm.c.