#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 = "88eaa8f5c1bd988bedd71113385e0886" , .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_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 3576 of file app_minivm.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 3576 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 3290 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().
03291 { 03292 char filename[BUFSIZ]; 03293 char readbuf[BUFSIZ]; 03294 FILE *counterfile; 03295 int old = 0, counter = 0; 03296 03297 /* Lock directory */ 03298 if (vm_lock_path(directory)) { 03299 return -1; /* Could not lock directory */ 03300 } 03301 snprintf(filename, sizeof(filename), "%s/%s.counter", directory, countername); 03302 if (operand != 1) { 03303 counterfile = fopen(filename, "r"); 03304 if (counterfile) { 03305 if(fgets(readbuf, sizeof(readbuf), counterfile)) { 03306 ast_debug(3, "Read this string from counter file: %s\n", readbuf); 03307 old = counter = atoi(readbuf); 03308 } 03309 fclose(counterfile); 03310 } 03311 } 03312 switch (operand) { 03313 case 0: /* Read only */ 03314 ast_unlock_path(directory); 03315 ast_debug(2, "MINIVM Counter %s/%s: Value %d\n", directory, countername, counter); 03316 return counter; 03317 break; 03318 case 1: /* Set new value */ 03319 counter = value; 03320 break; 03321 case 2: /* Change value */ 03322 counter += value; 03323 if (counter < 0) /* Don't allow counters to fall below zero */ 03324 counter = 0; 03325 break; 03326 } 03327 03328 /* Now, write the new value to the file */ 03329 counterfile = fopen(filename, "w"); 03330 if (!counterfile) { 03331 ast_log(LOG_ERROR, "Could not open counter file for writing : %s - %s\n", filename, strerror(errno)); 03332 ast_unlock_path(directory); 03333 return -1; /* Could not open file for writing */ 03334 } 03335 fprintf(counterfile, "%d\n\n", counter); 03336 fclose(counterfile); 03337 ast_unlock_path(directory); 03338 ast_debug(2, "MINIVM Counter %s/%s: Old value %d New value %d\n", directory, countername, old, counter); 03339 return counter; 03340 }
static int apply_general_options | ( | struct ast_variable * | var | ) | [static] |
Apply general configuration options.
Definition at line 2772 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().
02773 { 02774 int error = 0; 02775 02776 while (var) { 02777 /* Mail command */ 02778 if (!strcmp(var->name, "mailcmd")) { 02779 ast_copy_string(global_mailcmd, var->value, sizeof(global_mailcmd)); /* User setting */ 02780 } else if (!strcmp(var->name, "maxgreet")) { 02781 global_maxgreet = atoi(var->value); 02782 } else if (!strcmp(var->name, "maxsilence")) { 02783 global_maxsilence = atoi(var->value); 02784 if (global_maxsilence > 0) 02785 global_maxsilence *= 1000; 02786 } else if (!strcmp(var->name, "logfile")) { 02787 if (!ast_strlen_zero(var->value) ) { 02788 if(*(var->value) == '/') 02789 ast_copy_string(global_logfile, var->value, sizeof(global_logfile)); 02790 else 02791 snprintf(global_logfile, sizeof(global_logfile), "%s/%s", ast_config_AST_LOG_DIR, var->value); 02792 } 02793 } else if (!strcmp(var->name, "externnotify")) { 02794 /* External voicemail notify application */ 02795 ast_copy_string(global_externnotify, var->value, sizeof(global_externnotify)); 02796 } else if (!strcmp(var->name, "silencetreshold")) { 02797 /* Silence treshold */ 02798 global_silencethreshold = atoi(var->value); 02799 } else if (!strcmp(var->name, "maxmessage")) { 02800 int x; 02801 if (sscanf(var->value, "%30d", &x) == 1) { 02802 global_vmmaxmessage = x; 02803 } else { 02804 error ++; 02805 ast_log(LOG_WARNING, "Invalid max message time length\n"); 02806 } 02807 } else if (!strcmp(var->name, "minmessage")) { 02808 int x; 02809 if (sscanf(var->value, "%30d", &x) == 1) { 02810 global_vmminmessage = x; 02811 if (global_maxsilence <= global_vmminmessage) 02812 ast_log(LOG_WARNING, "maxsilence should be less than minmessage or you may get empty messages\n"); 02813 } else { 02814 error ++; 02815 ast_log(LOG_WARNING, "Invalid min message time length\n"); 02816 } 02817 } else if (!strcmp(var->name, "format")) { 02818 ast_copy_string(default_vmformat, var->value, sizeof(default_vmformat)); 02819 } else if (!strcmp(var->name, "review")) { 02820 ast_set2_flag((&globalflags), ast_true(var->value), MVM_REVIEW); 02821 } else if (!strcmp(var->name, "operator")) { 02822 ast_set2_flag((&globalflags), ast_true(var->value), MVM_OPERATOR); 02823 } 02824 var = var->next; 02825 } 02826 return error; 02827 }
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 1501 of file app_minivm.c.
References FALSE, make_dir(), and TRUE.
Referenced by leave_voicemail(), minivm_account_func_read(), and minivm_greet_exec().
01502 { 01503 struct stat filestat; 01504 make_dir(dest, len, domain, username, folder ? folder : ""); 01505 if (stat(dest, &filestat)== -1) 01506 return FALSE; 01507 else 01508 return TRUE; 01509 }
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 3011 of file app_minivm.c.
References AST_LIST_TRAVERSE, ast_strdup, minivm_account::domain, and minivm_account::list.
Referenced by handle_minivm_show_users().
03012 { 03013 int which = 0; 03014 int wordlen; 03015 struct minivm_account *vmu; 03016 const char *domain = ""; 03017 03018 /* 0 - voicemail; 1 - list; 2 - accounts; 3 - for; 4 - <domain> */ 03019 if (pos > 4) 03020 return NULL; 03021 if (pos == 3) 03022 return (state == 0) ? ast_strdup("for") : NULL; 03023 wordlen = strlen(word); 03024 AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) { 03025 if (!strncasecmp(word, vmu->domain, wordlen)) { 03026 if (domain && strcmp(domain, vmu->domain) && ++which > state) 03027 return ast_strdup(vmu->domain); 03028 /* ignore repeated domains ? */ 03029 domain = vmu->domain; 03030 } 03031 } 03032 return NULL; 03033 }
static int create_dirpath | ( | char * | dest, | |
int | len, | |||
char * | domain, | |||
char * | username, | |||
char * | folder | |||
) | [static] |
Definition at line 1520 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().
01521 { 01522 int res; 01523 make_dir(dest, len, domain, username, folder); 01524 if ((res = ast_mkdir(dest, 0777))) { 01525 ast_log(LOG_WARNING, "ast_mkdir '%s' failed: %s\n", dest, strerror(res)); 01526 return -1; 01527 } 01528 ast_debug(2, "Creating directory for %s@%s folder %s : %s\n", username, domain, folder, dest); 01529 return 0; 01530 }
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 2556 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().
02557 { 02558 struct minivm_account *vmu; 02559 char *domain; 02560 char *username; 02561 char accbuf[BUFSIZ]; 02562 02563 ast_debug(3, "Creating %s account for [%s]\n", realtime ? "realtime" : "static", name); 02564 02565 ast_copy_string(accbuf, name, sizeof(accbuf)); 02566 username = accbuf; 02567 domain = strchr(accbuf, '@'); 02568 if (domain) { 02569 *domain = '\0'; 02570 domain++; 02571 } 02572 if (ast_strlen_zero(domain)) { 02573 ast_log(LOG_ERROR, "No domain given for mini-voicemail account %s. Not configured.\n", name); 02574 return 0; 02575 } 02576 02577 ast_debug(3, "Creating static account for user %s domain %s\n", username, domain); 02578 02579 /* Allocate user account */ 02580 vmu = ast_calloc(1, sizeof(*vmu)); 02581 if (!vmu) 02582 return 0; 02583 02584 ast_copy_string(vmu->domain, domain, sizeof(vmu->domain)); 02585 ast_copy_string(vmu->username, username, sizeof(vmu->username)); 02586 02587 populate_defaults(vmu); 02588 02589 ast_debug(3, "...Configuring account %s\n", name); 02590 02591 while (var) { 02592 ast_debug(3, "Configuring %s = \"%s\" for account %s\n", var->name, var->value, name); 02593 if (!strcasecmp(var->name, "serveremail")) { 02594 ast_copy_string(vmu->serveremail, var->value, sizeof(vmu->serveremail)); 02595 } else if (!strcasecmp(var->name, "email")) { 02596 ast_copy_string(vmu->email, var->value, sizeof(vmu->email)); 02597 } else if (!strcasecmp(var->name, "accountcode")) { 02598 ast_copy_string(vmu->accountcode, var->value, sizeof(vmu->accountcode)); 02599 } else if (!strcasecmp(var->name, "pincode")) { 02600 ast_copy_string(vmu->pincode, var->value, sizeof(vmu->pincode)); 02601 } else if (!strcasecmp(var->name, "domain")) { 02602 ast_copy_string(vmu->domain, var->value, sizeof(vmu->domain)); 02603 } else if (!strcasecmp(var->name, "language")) { 02604 ast_copy_string(vmu->language, var->value, sizeof(vmu->language)); 02605 } else if (!strcasecmp(var->name, "timezone")) { 02606 ast_copy_string(vmu->zonetag, var->value, sizeof(vmu->zonetag)); 02607 } else if (!strcasecmp(var->name, "externnotify")) { 02608 ast_copy_string(vmu->externnotify, var->value, sizeof(vmu->externnotify)); 02609 } else if (!strcasecmp(var->name, "etemplate")) { 02610 ast_copy_string(vmu->etemplate, var->value, sizeof(vmu->etemplate)); 02611 } else if (!strcasecmp(var->name, "ptemplate")) { 02612 ast_copy_string(vmu->ptemplate, var->value, sizeof(vmu->ptemplate)); 02613 } else if (!strcasecmp(var->name, "fullname")) { 02614 ast_copy_string(vmu->fullname, var->value, sizeof(vmu->fullname)); 02615 } else if (!strcasecmp(var->name, "setvar")) { 02616 char *varval; 02617 char *varname = ast_strdupa(var->value); 02618 struct ast_variable *tmpvar; 02619 02620 if (varname && (varval = strchr(varname, '='))) { 02621 *varval = '\0'; 02622 varval++; 02623 if ((tmpvar = ast_variable_new(varname, varval, ""))) { 02624 tmpvar->next = vmu->chanvars; 02625 vmu->chanvars = tmpvar; 02626 } 02627 } 02628 } else if (!strcasecmp(var->name, "pager")) { 02629 ast_copy_string(vmu->pager, var->value, sizeof(vmu->pager)); 02630 } else if (!strcasecmp(var->name, "volgain")) { 02631 sscanf(var->value, "%30lf", &vmu->volgain); 02632 } else { 02633 ast_log(LOG_ERROR, "Unknown configuration option for minivm account %s : %s\n", name, var->name); 02634 } 02635 var = var->next; 02636 } 02637 ast_debug(3, "...Linking account %s\n", name); 02638 02639 AST_LIST_LOCK(&minivm_accounts); 02640 AST_LIST_INSERT_TAIL(&minivm_accounts, vmu, list); 02641 AST_LIST_UNLOCK(&minivm_accounts); 02642 02643 global_stats.voicemailaccounts++; 02644 02645 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)" : ""); 02646 return 0; 02647 }
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 2650 of file app_minivm.c.
References ast_free.
Referenced by free_vm_zones(), and timezone_destroy_list().
02651 { 02652 ast_free(z); 02653 }
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 2970 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.
02971 { 02972 struct minivm_template *this; 02973 #define HVLT_OUTPUT_FORMAT "%-15s %-10s %-10s %-15.15s %-50s\n" 02974 int count = 0; 02975 02976 switch (cmd) { 02977 case CLI_INIT: 02978 e->command = "minivm list templates"; 02979 e->usage = 02980 "Usage: minivm list templates\n" 02981 " Lists message templates for e-mail, paging and IM\n"; 02982 return NULL; 02983 case CLI_GENERATE: 02984 return NULL; 02985 } 02986 02987 if (a->argc > 3) 02988 return CLI_SHOWUSAGE; 02989 02990 AST_LIST_LOCK(&message_templates); 02991 if (AST_LIST_EMPTY(&message_templates)) { 02992 ast_cli(a->fd, "There are no message templates defined\n"); 02993 AST_LIST_UNLOCK(&message_templates); 02994 return CLI_FAILURE; 02995 } 02996 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "Template name", "Charset", "Locale", "Attach media", "Subject"); 02997 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, "-------------", "-------", "------", "------------", "-------"); 02998 AST_LIST_TRAVERSE(&message_templates, this, list) { 02999 ast_cli(a->fd, HVLT_OUTPUT_FORMAT, this->name, 03000 this->charset ? this->charset : "-", 03001 this->locale ? this->locale : "-", 03002 this->attachment ? "Yes" : "No", 03003 this->subject ? this->subject : "-"); 03004 count++; 03005 } 03006 AST_LIST_UNLOCK(&message_templates); 03007 ast_cli(a->fd, "\n * Total: %d minivoicemail message templates\n", count); 03008 return CLI_SUCCESS; 03009 }
static char * handle_minivm_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Reload cofiguration.
Definition at line 3529 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.
03530 { 03531 03532 switch (cmd) { 03533 case CLI_INIT: 03534 e->command = "minivm reload"; 03535 e->usage = 03536 "Usage: minivm reload\n" 03537 " Reload mini-voicemail configuration and reset statistics\n"; 03538 return NULL; 03539 case CLI_GENERATE: 03540 return NULL; 03541 } 03542 03543 reload(); 03544 ast_cli(a->fd, "\n-- Mini voicemail re-configured \n"); 03545 return CLI_SUCCESS; 03546 }
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 3121 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.
03122 { 03123 switch (cmd) { 03124 case CLI_INIT: 03125 e->command = "minivm show settings"; 03126 e->usage = 03127 "Usage: minivm show settings\n" 03128 " Display Mini-Voicemail general settings\n"; 03129 return NULL; 03130 case CLI_GENERATE: 03131 return NULL; 03132 } 03133 03134 ast_cli(a->fd, "* Mini-Voicemail general settings\n"); 03135 ast_cli(a->fd, " -------------------------------\n"); 03136 ast_cli(a->fd, "\n"); 03137 ast_cli(a->fd, " Mail command (shell): %s\n", global_mailcmd); 03138 ast_cli(a->fd, " Max silence: %d\n", global_maxsilence); 03139 ast_cli(a->fd, " Silence threshold: %d\n", global_silencethreshold); 03140 ast_cli(a->fd, " Max message length (secs): %d\n", global_vmmaxmessage); 03141 ast_cli(a->fd, " Min message length (secs): %d\n", global_vmminmessage); 03142 ast_cli(a->fd, " Default format: %s\n", default_vmformat); 03143 ast_cli(a->fd, " Extern notify (shell): %s\n", global_externnotify); 03144 ast_cli(a->fd, " Logfile: %s\n", global_logfile[0] ? global_logfile : "<disabled>"); 03145 ast_cli(a->fd, " Operator exit: %s\n", ast_test_flag(&globalflags, MVM_OPERATOR) ? "Yes" : "No"); 03146 ast_cli(a->fd, " Message review: %s\n", ast_test_flag(&globalflags, MVM_REVIEW) ? "Yes" : "No"); 03147 03148 ast_cli(a->fd, "\n"); 03149 return CLI_SUCCESS; 03150 }
static char* handle_minivm_show_stats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Show stats.
Definition at line 3153 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.
03154 { 03155 struct ast_tm timebuf; 03156 char buf[BUFSIZ]; 03157 03158 switch (cmd) { 03159 03160 case CLI_INIT: 03161 e->command = "minivm show stats"; 03162 e->usage = 03163 "Usage: minivm show stats\n" 03164 " Display Mini-Voicemail counters\n"; 03165 return NULL; 03166 case CLI_GENERATE: 03167 return NULL; 03168 } 03169 03170 ast_cli(a->fd, "* Mini-Voicemail statistics\n"); 03171 ast_cli(a->fd, " -------------------------\n"); 03172 ast_cli(a->fd, "\n"); 03173 ast_cli(a->fd, " Voicemail accounts: %5d\n", global_stats.voicemailaccounts); 03174 ast_cli(a->fd, " Templates: %5d\n", global_stats.templates); 03175 ast_cli(a->fd, " Timezones: %5d\n", global_stats.timezones); 03176 if (global_stats.receivedmessages == 0) { 03177 ast_cli(a->fd, " Received messages since last reset: <none>\n"); 03178 } else { 03179 ast_cli(a->fd, " Received messages since last reset: %d\n", global_stats.receivedmessages); 03180 ast_localtime(&global_stats.lastreceived, &timebuf, NULL); 03181 ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf); 03182 ast_cli(a->fd, " Last received voicemail: %s\n", buf); 03183 } 03184 ast_localtime(&global_stats.reset, &timebuf, NULL); 03185 ast_strftime(buf, sizeof(buf), "%a %b %e %r %Z %Y", &timebuf); 03186 ast_cli(a->fd, " Last reset: %s\n", buf); 03187 03188 ast_cli(a->fd, "\n"); 03189 return CLI_SUCCESS; 03190 }
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 3036 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.
03037 { 03038 struct minivm_account *vmu; 03039 #define HMSU_OUTPUT_FORMAT "%-23s %-15s %-15s %-10s %-10s %-50s\n" 03040 int count = 0; 03041 03042 switch (cmd) { 03043 case CLI_INIT: 03044 e->command = "minivm list accounts"; 03045 e->usage = 03046 "Usage: minivm list accounts\n" 03047 " Lists all mailboxes currently set up\n"; 03048 return NULL; 03049 case CLI_GENERATE: 03050 return complete_minivm_show_users(a->line, a->word, a->pos, a->n); 03051 } 03052 03053 if ((a->argc < 3) || (a->argc > 5) || (a->argc == 4)) 03054 return CLI_SHOWUSAGE; 03055 if ((a->argc == 5) && strcmp(a->argv[3],"for")) 03056 return CLI_SHOWUSAGE; 03057 03058 AST_LIST_LOCK(&minivm_accounts); 03059 if (AST_LIST_EMPTY(&minivm_accounts)) { 03060 ast_cli(a->fd, "There are no voicemail users currently defined\n"); 03061 AST_LIST_UNLOCK(&minivm_accounts); 03062 return CLI_FAILURE; 03063 } 03064 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "User", "E-Template", "P-template", "Zone", "Format", "Full name"); 03065 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, "----", "----------", "----------", "----", "------", "---------"); 03066 AST_LIST_TRAVERSE(&minivm_accounts, vmu, list) { 03067 char tmp[256] = ""; 03068 if ((a->argc == 3) || ((a->argc == 5) && !strcmp(a->argv[4], vmu->domain))) { 03069 count++; 03070 snprintf(tmp, sizeof(tmp), "%s@%s", vmu->username, vmu->domain); 03071 ast_cli(a->fd, HMSU_OUTPUT_FORMAT, tmp, vmu->etemplate ? vmu->etemplate : "-", 03072 vmu->ptemplate ? vmu->ptemplate : "-", 03073 vmu->zonetag ? vmu->zonetag : "-", 03074 vmu->attachfmt ? vmu->attachfmt : "-", 03075 vmu->fullname); 03076 } 03077 } 03078 AST_LIST_UNLOCK(&minivm_accounts); 03079 ast_cli(a->fd, "\n * Total: %d minivoicemail accounts\n", count); 03080 return CLI_SUCCESS; 03081 }
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 3084 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.
03085 { 03086 struct minivm_zone *zone; 03087 #define HMSZ_OUTPUT_FORMAT "%-15s %-20s %-45s\n" 03088 char *res = CLI_SUCCESS; 03089 03090 switch (cmd) { 03091 case CLI_INIT: 03092 e->command = "minivm list zones"; 03093 e->usage = 03094 "Usage: minivm list zones\n" 03095 " Lists zone message formats\n"; 03096 return NULL; 03097 case CLI_GENERATE: 03098 return NULL; 03099 } 03100 03101 if (a->argc != e->args) 03102 return CLI_SHOWUSAGE; 03103 03104 AST_LIST_LOCK(&minivm_zones); 03105 if (!AST_LIST_EMPTY(&minivm_zones)) { 03106 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "Zone", "Timezone", "Message Format"); 03107 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, "----", "--------", "--------------"); 03108 AST_LIST_TRAVERSE(&minivm_zones, zone, list) { 03109 ast_cli(a->fd, HMSZ_OUTPUT_FORMAT, zone->name, zone->timezone, zone->msg_format); 03110 } 03111 } else { 03112 ast_cli(a->fd, "There are no voicemail zones currently defined\n"); 03113 res = CLI_FAILURE; 03114 } 03115 AST_LIST_UNLOCK(&minivm_zones); 03116 03117 return res; 03118 }
static int invent_message | ( | struct ast_channel * | chan, | |
char * | domain, | |||
char * | username, | |||
int | busy, | |||
char * | ecodes | |||
) | [static] |
Definition at line 1536 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().
01537 { 01538 int res; 01539 char fn[PATH_MAX]; 01540 01541 ast_debug(2, "Still preparing to play message ...\n"); 01542 01543 snprintf(fn, sizeof(fn), "%s%s/%s/greet", MVM_SPOOL_DIR, domain, username); 01544 01545 if (ast_fileexists(fn, NULL, NULL) > 0) { 01546 res = ast_streamfile(chan, fn, chan->language); 01547 if (res) 01548 return -1; 01549 res = ast_waitstream(chan, ecodes); 01550 if (res) 01551 return res; 01552 } else { 01553 int numericusername = 1; 01554 char *i = username; 01555 01556 ast_debug(2, "No personal prompts. Using default prompt set for language\n"); 01557 01558 while (*i) { 01559 ast_debug(2, "Numeric? Checking %c\n", *i); 01560 if (!isdigit(*i)) { 01561 numericusername = FALSE; 01562 break; 01563 } 01564 i++; 01565 } 01566 01567 if (numericusername) { 01568 if (ast_streamfile(chan, "vm-theperson", chan->language)) 01569 return -1; 01570 if ((res = ast_waitstream(chan, ecodes))) 01571 return res; 01572 01573 res = ast_say_digit_str(chan, username, ecodes, chan->language); 01574 if (res) 01575 return res; 01576 } else { 01577 if (ast_streamfile(chan, "vm-theextensionis", chan->language)) 01578 return -1; 01579 if ((res = ast_waitstream(chan, ecodes))) 01580 return res; 01581 } 01582 } 01583 01584 res = ast_streamfile(chan, busy ? "vm-isonphone" : "vm-isunavail", chan->language); 01585 if (res) 01586 return -1; 01587 res = ast_waitstream(chan, ecodes); 01588 return res; 01589 }
static int leave_voicemail | ( | struct ast_channel * | chan, | |
char * | username, | |||
struct leave_vm_options * | options | |||
) | [static] |
Definition at line 1840 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().
01841 { 01842 char tmptxtfile[PATH_MAX]; 01843 char callerid[256]; 01844 FILE *txt; 01845 int res = 0, txtdes; 01846 int duration = 0; 01847 int sound_duration = 0; 01848 char date[256]; 01849 char tmpdir[PATH_MAX]; 01850 char ext_context[256] = ""; 01851 char fmt[80]; 01852 char *domain; 01853 char tmp[256] = ""; 01854 struct minivm_account *vmu; 01855 int userdir; 01856 01857 ast_copy_string(tmp, username, sizeof(tmp)); 01858 username = tmp; 01859 domain = strchr(tmp, '@'); 01860 if (domain) { 01861 *domain = '\0'; 01862 domain++; 01863 } 01864 01865 if (!(vmu = find_account(domain, username, TRUE))) { 01866 /* We could not find user, let's exit */ 01867 ast_log(LOG_ERROR, "Can't allocate temporary account for '%s@%s'\n", username, domain); 01868 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01869 return 0; 01870 } 01871 01872 /* Setup pre-file if appropriate */ 01873 if (strcmp(vmu->domain, "localhost")) 01874 snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain); 01875 else 01876 ast_copy_string(ext_context, vmu->domain, sizeof(ext_context)); 01877 01878 /* The meat of recording the message... All the announcements and beeps have been played*/ 01879 if (ast_strlen_zero(vmu->attachfmt)) 01880 ast_copy_string(fmt, default_vmformat, sizeof(fmt)); 01881 else 01882 ast_copy_string(fmt, vmu->attachfmt, sizeof(fmt)); 01883 01884 if (ast_strlen_zero(fmt)) { 01885 ast_log(LOG_WARNING, "No format for saving voicemail? Default %s\n", default_vmformat); 01886 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01887 return res; 01888 } 01889 01890 userdir = check_dirpath(tmpdir, sizeof(tmpdir), vmu->domain, username, "tmp"); 01891 01892 /* If we have no user directory, use generic temporary directory */ 01893 if (!userdir) { 01894 create_dirpath(tmpdir, sizeof(tmpdir), "0000_minivm_temp", "mediafiles", ""); 01895 ast_debug(3, "Creating temporary directory %s\n", tmpdir); 01896 } 01897 01898 01899 snprintf(tmptxtfile, sizeof(tmptxtfile), "%s/XXXXXX", tmpdir); 01900 01901 /* XXX This file needs to be in temp directory */ 01902 txtdes = mkstemp(tmptxtfile); 01903 if (txtdes < 0) { 01904 ast_log(LOG_ERROR, "Unable to create message file %s: %s\n", tmptxtfile, strerror(errno)); 01905 res = ast_streamfile(chan, "vm-mailboxfull", chan->language); 01906 if (!res) 01907 res = ast_waitstream(chan, ""); 01908 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01909 return res; 01910 } 01911 01912 if (res >= 0) { 01913 /* Unless we're *really* silent, try to send the beep */ 01914 res = ast_streamfile(chan, "beep", chan->language); 01915 if (!res) 01916 res = ast_waitstream(chan, ""); 01917 } 01918 01919 /* OEJ XXX Maybe this can be turned into a log file? Hmm. */ 01920 /* Store information */ 01921 ast_debug(2, "Open file for metadata: %s\n", tmptxtfile); 01922 01923 res = play_record_review(chan, NULL, tmptxtfile, global_vmmaxmessage, fmt, 1, vmu, &duration, &sound_duration, NULL, options->record_gain); 01924 01925 txt = fdopen(txtdes, "w+"); 01926 if (!txt) { 01927 ast_log(LOG_WARNING, "Error opening text file for output\n"); 01928 } else { 01929 struct ast_tm tm; 01930 struct timeval now = ast_tvnow(); 01931 char timebuf[30]; 01932 char logbuf[BUFSIZ]; 01933 get_date(date, sizeof(date)); 01934 ast_localtime(&now, &tm, NULL); 01935 ast_strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &tm); 01936 01937 ast_callerid_merge(callerid, sizeof(callerid), 01938 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL), 01939 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 01940 "Unknown"); 01941 snprintf(logbuf, sizeof(logbuf), 01942 /* "Mailbox:domain:macrocontext:exten:priority:callerchan:callerid:origdate:origtime:duration:durationstatus:accountcode" */ 01943 "%s:%s:%s:%s:%d:%s:%s:%s:%s:%d:%s:%s\n", 01944 username, 01945 chan->context, 01946 chan->macrocontext, 01947 chan->exten, 01948 chan->priority, 01949 chan->name, 01950 callerid, 01951 date, 01952 timebuf, 01953 duration, 01954 duration < global_vmminmessage ? "IGNORED" : "OK", 01955 vmu->accountcode 01956 ); 01957 fprintf(txt, "%s", logbuf); 01958 if (minivmlogfile) { 01959 ast_mutex_lock(&minivmloglock); 01960 fprintf(minivmlogfile, "%s", logbuf); 01961 ast_mutex_unlock(&minivmloglock); 01962 } 01963 01964 if (sound_duration < global_vmminmessage) { 01965 ast_verb(3, "Recording was %d seconds long but needs to be at least %d - abandoning\n", sound_duration, global_vmminmessage); 01966 fclose(txt); 01967 ast_filedelete(tmptxtfile, NULL); 01968 unlink(tmptxtfile); 01969 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01970 return 0; 01971 } 01972 fclose(txt); /* Close log file */ 01973 if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 01974 ast_debug(1, "The recorded media file is gone, so we should remove the .txt file too!\n"); 01975 unlink(tmptxtfile); 01976 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 01977 if(ast_test_flag(vmu, MVM_ALLOCED)) 01978 free_user(vmu); 01979 return 0; 01980 } 01981 01982 /* Set channel variables for the notify application */ 01983 pbx_builtin_setvar_helper(chan, "MVM_FILENAME", tmptxtfile); 01984 snprintf(timebuf, sizeof(timebuf), "%d", duration); 01985 pbx_builtin_setvar_helper(chan, "MVM_DURATION", timebuf); 01986 pbx_builtin_setvar_helper(chan, "MVM_FORMAT", fmt); 01987 01988 } 01989 global_stats.lastreceived = ast_tvnow(); 01990 global_stats.receivedmessages++; 01991 #if 0 01992 /* Go ahead and delete audio files from system, they're not needed any more */ 01993 if (ast_fileexists(tmptxtfile, NULL, NULL) <= 0) { 01994 ast_filedelete(tmptxtfile, NULL); 01995 /* Even not being used at the moment, it's better to convert ast_log to ast_debug anyway */ 01996 ast_debug(2, "-_-_- Deleted audio file after notification :: %s \n", tmptxtfile); 01997 } 01998 #endif 01999 02000 if (res > 0) 02001 res = 0; 02002 02003 if(ast_test_flag(vmu, MVM_ALLOCED)) 02004 free_user(vmu); 02005 02006 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS"); 02007 return res; 02008 }
static int load_config | ( | int | reload | ) | [static] |
Load minivoicemail configuration.
Definition at line 2830 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_flags, 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.
02831 { 02832 struct ast_config *cfg; 02833 struct ast_variable *var; 02834 char *cat; 02835 const char *chanvar; 02836 int error = 0; 02837 struct minivm_template *template; 02838 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 02839 02840 cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags); 02841 if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 02842 return 0; 02843 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 02844 ast_log(LOG_ERROR, "Config file " VOICEMAIL_CONFIG " is in an invalid format. Aborting.\n"); 02845 return 0; 02846 } 02847 02848 ast_mutex_lock(&minivmlock); 02849 02850 /* Destroy lists to reconfigure */ 02851 message_destroy_list(); /* Destroy list of voicemail message templates */ 02852 timezone_destroy_list(); /* Destroy list of timezones */ 02853 vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */ 02854 ast_debug(2, "Destroyed memory objects...\n"); 02855 02856 /* First, set some default settings */ 02857 global_externnotify[0] = '\0'; 02858 global_logfile[0] = '\0'; 02859 global_vmmaxmessage = 2000; 02860 global_maxgreet = 2000; 02861 global_vmminmessage = 0; 02862 strcpy(global_mailcmd, SENDMAIL); 02863 global_maxsilence = 0; 02864 global_saydurationminfo = 2; 02865 ast_copy_string(default_vmformat, "wav", sizeof(default_vmformat)); 02866 ast_set2_flag((&globalflags), FALSE, MVM_REVIEW); 02867 ast_set2_flag((&globalflags), FALSE, MVM_OPERATOR); 02868 /* Reset statistics */ 02869 memset(&global_stats, 0, sizeof(global_stats)); 02870 global_stats.reset = ast_tvnow(); 02871 02872 global_silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE); 02873 02874 /* Make sure we could load configuration file */ 02875 if (!cfg) { 02876 ast_log(LOG_WARNING, "Failed to load configuration file. Module activated with default settings.\n"); 02877 ast_mutex_unlock(&minivmlock); 02878 return 0; 02879 } 02880 02881 ast_debug(2, "Loaded configuration file, now parsing\n"); 02882 02883 /* General settings */ 02884 02885 cat = ast_category_browse(cfg, NULL); 02886 while (cat) { 02887 ast_debug(3, "Found configuration section [%s]\n", cat); 02888 if (!strcasecmp(cat, "general")) { 02889 /* Nothing right now */ 02890 error += apply_general_options(ast_variable_browse(cfg, cat)); 02891 } else if (!strncasecmp(cat, "template-", 9)) { 02892 /* Template */ 02893 char *name = cat + 9; 02894 02895 /* Now build and link template to list */ 02896 error += message_template_build(name, ast_variable_browse(cfg, cat)); 02897 } else { 02898 var = ast_variable_browse(cfg, cat); 02899 if (!strcasecmp(cat, "zonemessages")) { 02900 /* Timezones in this context */ 02901 while (var) { 02902 timezone_add(var->name, var->value); 02903 var = var->next; 02904 } 02905 } else { 02906 /* Create mailbox from this */ 02907 error += create_vmaccount(cat, var, FALSE); 02908 } 02909 } 02910 /* Find next section in configuration file */ 02911 cat = ast_category_browse(cfg, cat); 02912 } 02913 02914 /* Configure the default email template */ 02915 message_template_build("email-default", NULL); 02916 template = message_template_find("email-default"); 02917 02918 /* Load date format config for voicemail mail */ 02919 if ((chanvar = ast_variable_retrieve(cfg, "general", "emaildateformat"))) 02920 ast_copy_string(template->dateformat, chanvar, sizeof(template->dateformat)); 02921 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailfromstring"))) 02922 ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress)); 02923 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailaaddress"))) 02924 ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail)); 02925 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailcharset"))) 02926 ast_copy_string(template->charset, chanvar, sizeof(template->charset)); 02927 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailsubject"))) 02928 ast_copy_string(template->subject, chanvar, sizeof(template->subject)); 02929 if ((chanvar = ast_variable_retrieve(cfg, "general", "emailbody"))) 02930 template->body = message_template_parse_emailbody(chanvar); 02931 template->attachment = TRUE; 02932 02933 message_template_build("pager-default", NULL); 02934 template = message_template_find("pager-default"); 02935 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerfromstring"))) 02936 ast_copy_string(template->fromaddress, chanvar, sizeof(template->fromaddress)); 02937 if ((chanvar = ast_variable_retrieve(cfg, "general", "pageraddress"))) 02938 ast_copy_string(template->serveremail, chanvar, sizeof(template->serveremail)); 02939 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagercharset"))) 02940 ast_copy_string(template->charset, chanvar, sizeof(template->charset)); 02941 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagersubject"))) 02942 ast_copy_string(template->subject, chanvar,sizeof(template->subject)); 02943 if ((chanvar = ast_variable_retrieve(cfg, "general", "pagerbody"))) 02944 template->body = message_template_parse_emailbody(chanvar); 02945 template->attachment = FALSE; 02946 02947 if (error) 02948 ast_log(LOG_ERROR, "--- A total of %d errors found in mini-voicemail configuration\n", error); 02949 02950 ast_mutex_unlock(&minivmlock); 02951 ast_config_destroy(cfg); 02952 02953 /* Close log file if it's open and disabled */ 02954 if(minivmlogfile) 02955 fclose(minivmlogfile); 02956 02957 /* Open log file if it's enabled */ 02958 if(!ast_strlen_zero(global_logfile)) { 02959 minivmlogfile = fopen(global_logfile, "a"); 02960 if(!minivmlogfile) 02961 ast_log(LOG_ERROR, "Failed to open minivm log file %s : %s\n", global_logfile, strerror(errno)); 02962 if (minivmlogfile) 02963 ast_debug(3, "Opened log file %s \n", global_logfile); 02964 } 02965 02966 return 0; 02967 }
static int load_module | ( | void | ) | [static] |
Load mini voicemail module.
Definition at line 3495 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().
03496 { 03497 int res; 03498 03499 res = ast_register_application_xml(app_minivm_record, minivm_record_exec); 03500 res = ast_register_application_xml(app_minivm_greet, minivm_greet_exec); 03501 res = ast_register_application_xml(app_minivm_notify, minivm_notify_exec); 03502 res = ast_register_application_xml(app_minivm_delete, minivm_delete_exec); 03503 res = ast_register_application_xml(app_minivm_accmess, minivm_accmess_exec); 03504 res = ast_register_application_xml(app_minivm_mwi, minivm_mwi_exec); 03505 03506 ast_custom_function_register(&minivm_account_function); 03507 ast_custom_function_register(&minivm_counter_function); 03508 if (res) 03509 return(res); 03510 03511 if ((res = load_config(0))) 03512 return(res); 03513 03514 ast_cli_register_multiple(cli_minivm, ARRAY_LEN(cli_minivm)); 03515 03516 /* compute the location of the voicemail spool directory */ 03517 snprintf(MVM_SPOOL_DIR, sizeof(MVM_SPOOL_DIR), "%s/voicemail/", ast_config_AST_SPOOL_DIR); 03518 03519 return res; 03520 }
static int make_dir | ( | char * | dest, | |
int | len, | |||
const char * | domain, | |||
const char * | username, | |||
const char * | folder | |||
) | [static] |
Definition at line 1487 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().
01488 { 01489 return snprintf(dest, len, "%s%s/%s%s%s", MVM_SPOOL_DIR, domain, username, ast_strlen_zero(folder) ? "" : "/", folder ? folder : ""); 01490 }
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 2745 of file app_minivm.c.
References ast_log(), ast_strdup, emailbody, len(), and LOG_NOTICE.
Referenced by load_config(), and message_template_build().
02746 { 02747 char *tmpread, *tmpwrite; 02748 char *emailbody = ast_strdup(configuration); 02749 02750 /* substitute strings \t and \n into the apropriate characters */ 02751 tmpread = tmpwrite = emailbody; 02752 while ((tmpwrite = strchr(tmpread,'\\'))) { 02753 int len = strlen("\n"); 02754 switch (tmpwrite[1]) { 02755 case 'n': 02756 memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1); 02757 strncpy(tmpwrite, "\n", len); 02758 break; 02759 case 't': 02760 memmove(tmpwrite + len, tmpwrite + 2, strlen(tmpwrite + 2) + 1); 02761 strncpy(tmpwrite, "\t", len); 02762 break; 02763 default: 02764 ast_log(LOG_NOTICE, "Substitution routine does not support this character: %c\n", tmpwrite[1]); 02765 } 02766 tmpread = tmpwrite + len; 02767 } 02768 return emailbody; 02769 }
static char * message_template_parse_filebody | ( | const char * | filename | ) | [static] |
Read message template from file.
Definition at line 2705 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().
02705 { 02706 char buf[BUFSIZ * 6]; 02707 char readbuf[BUFSIZ]; 02708 char filenamebuf[BUFSIZ]; 02709 char *writepos; 02710 char *messagebody; 02711 FILE *fi; 02712 int lines = 0; 02713 02714 if (ast_strlen_zero(filename)) 02715 return NULL; 02716 if (*filename == '/') 02717 ast_copy_string(filenamebuf, filename, sizeof(filenamebuf)); 02718 else 02719 snprintf(filenamebuf, sizeof(filenamebuf), "%s/%s", ast_config_AST_CONFIG_DIR, filename); 02720 02721 if (!(fi = fopen(filenamebuf, "r"))) { 02722 ast_log(LOG_ERROR, "Can't read message template from file: %s\n", filenamebuf); 02723 return NULL; 02724 } 02725 writepos = buf; 02726 while (fgets(readbuf, sizeof(readbuf), fi)) { 02727 lines ++; 02728 if (writepos != buf) { 02729 *writepos = '\n'; /* Replace EOL with new line */ 02730 writepos++; 02731 } 02732 ast_copy_string(writepos, readbuf, sizeof(buf) - (writepos - buf)); 02733 writepos += strlen(readbuf) - 1; 02734 } 02735 fclose(fi); 02736 messagebody = ast_calloc(1, strlen(buf + 1)); 02737 ast_copy_string(messagebody, buf, strlen(buf) + 1); 02738 ast_debug(4, "---> Size of allocation %d\n", (int) strlen(buf + 1) ); 02739 ast_debug(4, "---> Done reading message template : \n%s\n---- END message template--- \n", messagebody); 02740 02741 return messagebody; 02742 }
static int minivm_accmess_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Record specific messages for voicemail account.
Definition at line 2453 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().
02454 { 02455 int argc = 0; 02456 char *argv[2]; 02457 char filename[PATH_MAX]; 02458 char tmp[PATH_MAX]; 02459 char *domain; 02460 char *tmpptr = NULL; 02461 struct minivm_account *vmu; 02462 char *username = argv[0]; 02463 struct ast_flags flags = { 0 }; 02464 char *opts[OPT_ARG_ARRAY_SIZE]; 02465 int error = FALSE; 02466 char *message = NULL; 02467 char *prompt = NULL; 02468 int duration; 02469 02470 if (ast_strlen_zero(data)) { 02471 ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n"); 02472 error = TRUE; 02473 } else 02474 tmpptr = ast_strdupa((char *)data); 02475 if (!error) { 02476 if (!tmpptr) { 02477 ast_log(LOG_ERROR, "Out of memory\n"); 02478 error = TRUE; 02479 } else 02480 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02481 } 02482 02483 if (argc <=1) { 02484 ast_log(LOG_ERROR, "MinivmAccmess needs at least two arguments: account and option\n"); 02485 error = TRUE; 02486 } 02487 if (!error && strlen(argv[1]) > 1) { 02488 ast_log(LOG_ERROR, "MinivmAccmess can only handle one option at a time. Bad option string: %s\n", argv[1]); 02489 error = TRUE; 02490 } 02491 02492 if (!error && ast_app_parse_options(minivm_accmess_options, &flags, opts, argv[1])) { 02493 ast_log(LOG_ERROR, "Can't parse option %s\n", argv[1]); 02494 error = TRUE; 02495 } 02496 02497 if (error) { 02498 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02499 return -1; 02500 } 02501 02502 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02503 username = tmp; 02504 domain = strchr(tmp, '@'); 02505 if (domain) { 02506 *domain = '\0'; 02507 domain++; 02508 } 02509 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 02510 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]); 02511 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02512 return -1; 02513 } 02514 02515 if(!(vmu = find_account(domain, username, TRUE))) { 02516 /* We could not find user, let's exit */ 02517 ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain); 02518 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "FAILED"); 02519 return -1; 02520 } 02521 02522 /* Answer channel if it's not already answered */ 02523 if (chan->_state != AST_STATE_UP) 02524 ast_answer(chan); 02525 02526 /* Here's where the action is */ 02527 if (ast_test_flag(&flags, OPT_BUSY_GREETING)) { 02528 message = "busy"; 02529 prompt = "vm-rec-busy"; 02530 } else if (ast_test_flag(&flags, OPT_UNAVAIL_GREETING)) { 02531 message = "unavailable"; 02532 prompt = "vm-rec-unv"; 02533 } else if (ast_test_flag(&flags, OPT_TEMP_GREETING)) { 02534 message = "temp"; 02535 prompt = "vm-rec-temp"; 02536 } else if (ast_test_flag(&flags, OPT_NAME_GREETING)) { 02537 message = "greet"; 02538 prompt = "vm-rec-name"; 02539 } 02540 snprintf(filename,sizeof(filename), "%s%s/%s/%s", MVM_SPOOL_DIR, vmu->domain, vmu->username, message); 02541 /* Maybe we should check the result of play_record_review ? */ 02542 play_record_review(chan, prompt, filename, global_maxgreet, default_vmformat, 0, vmu, &duration, NULL, NULL, FALSE); 02543 02544 ast_debug(1, "Recorded new %s message in %s (duration %d)\n", message, filename, duration); 02545 02546 if(ast_test_flag(vmu, MVM_ALLOCED)) 02547 free_user(vmu); 02548 02549 pbx_builtin_setvar_helper(chan, "MVM_ACCMESS_STATUS", "SUCCESS"); 02550 02551 /* Ok, we're ready to rock and roll. Return to dialplan */ 02552 return 0; 02553 }
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 3193 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.
03194 { 03195 struct minivm_account *vmu; 03196 char *username, *domain, *colname; 03197 03198 if (!(username = ast_strdupa(data))) { 03199 ast_log(LOG_ERROR, "Memory Error!\n"); 03200 return -1; 03201 } 03202 03203 if ((colname = strchr(username, ':'))) { 03204 *colname = '\0'; 03205 colname++; 03206 } else { 03207 colname = "path"; 03208 } 03209 if ((domain = strchr(username, '@'))) { 03210 *domain = '\0'; 03211 domain++; 03212 } 03213 if (ast_strlen_zero(username) || ast_strlen_zero(domain)) { 03214 ast_log(LOG_ERROR, "This function needs a username and a domain: username@domain\n"); 03215 return 0; 03216 } 03217 03218 if (!(vmu = find_account(domain, username, TRUE))) 03219 return 0; 03220 03221 if (!strcasecmp(colname, "hasaccount")) { 03222 ast_copy_string(buf, (ast_test_flag(vmu, MVM_ALLOCED) ? "0" : "1"), len); 03223 } else if (!strcasecmp(colname, "fullname")) { 03224 ast_copy_string(buf, vmu->fullname, len); 03225 } else if (!strcasecmp(colname, "email")) { 03226 if (!ast_strlen_zero(vmu->email)) 03227 ast_copy_string(buf, vmu->email, len); 03228 else 03229 snprintf(buf, len, "%s@%s", vmu->username, vmu->domain); 03230 } else if (!strcasecmp(colname, "pager")) { 03231 ast_copy_string(buf, vmu->pager, len); 03232 } else if (!strcasecmp(colname, "etemplate")) { 03233 if (!ast_strlen_zero(vmu->etemplate)) 03234 ast_copy_string(buf, vmu->etemplate, len); 03235 else 03236 ast_copy_string(buf, "email-default", len); 03237 } else if (!strcasecmp(colname, "language")) { 03238 ast_copy_string(buf, vmu->language, len); 03239 } else if (!strcasecmp(colname, "timezone")) { 03240 ast_copy_string(buf, vmu->zonetag, len); 03241 } else if (!strcasecmp(colname, "ptemplate")) { 03242 if (!ast_strlen_zero(vmu->ptemplate)) 03243 ast_copy_string(buf, vmu->ptemplate, len); 03244 else 03245 ast_copy_string(buf, "email-default", len); 03246 } else if (!strcasecmp(colname, "accountcode")) { 03247 ast_copy_string(buf, vmu->accountcode, len); 03248 } else if (!strcasecmp(colname, "pincode")) { 03249 ast_copy_string(buf, vmu->pincode, len); 03250 } else if (!strcasecmp(colname, "path")) { 03251 check_dirpath(buf, len, vmu->domain, vmu->username, NULL); 03252 } else { /* Look in channel variables */ 03253 struct ast_variable *var; 03254 03255 for (var = vmu->chanvars ; var ; var = var->next) 03256 if (!strcmp(var->name, colname)) { 03257 ast_copy_string(buf, var->value, len); 03258 break; 03259 } 03260 } 03261 03262 if(ast_test_flag(vmu, MVM_ALLOCED)) 03263 free_user(vmu); 03264 03265 return 0; 03266 }
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 3343 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.
03344 { 03345 char *username, *domain, *countername; 03346 struct minivm_account *vmu = NULL; 03347 char userpath[BUFSIZ]; 03348 int res; 03349 03350 *buf = '\0'; 03351 03352 if (!(username = ast_strdupa(data))) { /* Copy indata to local buffer */ 03353 ast_log(LOG_WARNING, "Memory error!\n"); 03354 return -1; 03355 } 03356 if ((countername = strchr(username, ':'))) { 03357 *countername = '\0'; 03358 countername++; 03359 } 03360 03361 if ((domain = strchr(username, '@'))) { 03362 *domain = '\0'; 03363 domain++; 03364 } 03365 03366 /* If we have neither username nor domain now, let's give up */ 03367 if (ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03368 ast_log(LOG_ERROR, "No account given\n"); 03369 return -1; 03370 } 03371 03372 if (ast_strlen_zero(countername)) { 03373 ast_log(LOG_ERROR, "This function needs two arguments: Account:countername\n"); 03374 return -1; 03375 } 03376 03377 /* We only have a domain, no username */ 03378 if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03379 domain = username; 03380 username = NULL; 03381 } 03382 03383 /* If we can't find account or if the account is temporary, return. */ 03384 if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) { 03385 ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain); 03386 return 0; 03387 } 03388 03389 create_dirpath(userpath, sizeof(userpath), domain, username, NULL); 03390 03391 /* We have the path, now read the counter file */ 03392 res = access_counter_file(userpath, countername, 0, 0); 03393 if (res >= 0) 03394 snprintf(buf, len, "%d", res); 03395 return 0; 03396 }
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 3399 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.
03400 { 03401 char *username, *domain, *countername, *operand; 03402 char userpath[BUFSIZ]; 03403 struct minivm_account *vmu; 03404 int change = 0; 03405 int operation = 0; 03406 03407 if(!value) 03408 return -1; 03409 change = atoi(value); 03410 03411 if (!(username = ast_strdupa(data))) { /* Copy indata to local buffer */ 03412 ast_log(LOG_WARNING, "Memory error!\n"); 03413 return -1; 03414 } 03415 03416 if ((countername = strchr(username, ':'))) { 03417 *countername = '\0'; 03418 countername++; 03419 } 03420 if ((operand = strchr(countername, ':'))) { 03421 *operand = '\0'; 03422 operand++; 03423 } 03424 03425 if ((domain = strchr(username, '@'))) { 03426 *domain = '\0'; 03427 domain++; 03428 } 03429 03430 /* If we have neither username nor domain now, let's give up */ 03431 if (ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03432 ast_log(LOG_ERROR, "No account given\n"); 03433 return -1; 03434 } 03435 03436 /* We only have a domain, no username */ 03437 if (!ast_strlen_zero(username) && ast_strlen_zero(domain)) { 03438 domain = username; 03439 username = NULL; 03440 } 03441 03442 if (ast_strlen_zero(operand) || ast_strlen_zero(countername)) { 03443 ast_log(LOG_ERROR, "Writing to this function requires three arguments: Account:countername:operand\n"); 03444 return -1; 03445 } 03446 03447 /* If we can't find account or if the account is temporary, return. */ 03448 if (!ast_strlen_zero(username) && !(vmu = find_account(domain, username, FALSE))) { 03449 ast_log(LOG_ERROR, "Minivm account does not exist: %s@%s\n", username, domain); 03450 return 0; 03451 } 03452 03453 create_dirpath(userpath, sizeof(userpath), domain, username, NULL); 03454 /* Now, find out our operator */ 03455 if (*operand == 'i') /* Increment */ 03456 operation = 2; 03457 else if (*operand == 'd') { 03458 change = change * -1; 03459 operation = 2; 03460 } else if (*operand == 's') 03461 operation = 1; 03462 else { 03463 ast_log(LOG_ERROR, "Unknown operator: %s\n", operand); 03464 return -1; 03465 } 03466 03467 /* We have the path, now read the counter file */ 03468 access_counter_file(userpath, countername, change, operation); 03469 return 0; 03470 }
static int minivm_delete_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 2415 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().
02416 { 02417 int res = 0; 02418 char filename[BUFSIZ]; 02419 02420 if (!ast_strlen_zero(data)) { 02421 ast_copy_string(filename, (char *) data, sizeof(filename)); 02422 } else { 02423 ast_channel_lock(chan); 02424 ast_copy_string(filename, pbx_builtin_getvar_helper(chan, "MVM_FILENAME"), sizeof(filename)); 02425 ast_channel_unlock(chan); 02426 } 02427 02428 if (ast_strlen_zero(filename)) { 02429 ast_log(LOG_ERROR, "No filename given in application arguments or channel variable MVM_FILENAME\n"); 02430 return res; 02431 } 02432 02433 /* Go ahead and delete audio files from system, they're not needed any more */ 02434 /* We should look for both audio and text files here */ 02435 if (ast_fileexists(filename, NULL, NULL) > 0) { 02436 res = vm_delete(filename); 02437 if (res) { 02438 ast_debug(2, "Can't delete file: %s\n", filename); 02439 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED"); 02440 } else { 02441 ast_debug(2, "Deleted voicemail file :: %s \n", filename); 02442 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "SUCCESS"); 02443 } 02444 } else { 02445 ast_debug(2, "Filename does not exist: %s\n", filename); 02446 pbx_builtin_setvar_helper(chan, "MVM_DELETE_STATUS", "FAILED"); 02447 } 02448 02449 return res; 02450 }
static int minivm_greet_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 2219 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().
02220 { 02221 struct leave_vm_options leave_options = { 0, '\0'}; 02222 int argc; 02223 char *argv[2]; 02224 struct ast_flags flags = { 0 }; 02225 char *opts[OPT_ARG_ARRAY_SIZE]; 02226 int res = 0; 02227 int ausemacro = 0; 02228 int ousemacro = 0; 02229 int ouseexten = 0; 02230 char tmp[PATH_MAX]; 02231 char dest[PATH_MAX]; 02232 char prefile[PATH_MAX] = ""; 02233 char tempfile[PATH_MAX] = ""; 02234 char ext_context[256] = ""; 02235 char *domain; 02236 char ecodes[16] = "#"; 02237 char *tmpptr; 02238 struct minivm_account *vmu; 02239 char *username = argv[0]; 02240 02241 if (ast_strlen_zero(data)) { 02242 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 02243 return -1; 02244 } 02245 tmpptr = ast_strdupa((char *)data); 02246 if (!tmpptr) { 02247 ast_log(LOG_ERROR, "Out of memory\n"); 02248 return -1; 02249 } 02250 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02251 02252 if (argc == 2) { 02253 if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) 02254 return -1; 02255 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING ); 02256 } 02257 02258 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02259 username = tmp; 02260 domain = strchr(tmp, '@'); 02261 if (domain) { 02262 *domain = '\0'; 02263 domain++; 02264 } 02265 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 02266 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument: %s\n", argv[0]); 02267 return -1; 02268 } 02269 ast_debug(1, "Trying to find configuration for user %s in domain %s\n", username, domain); 02270 02271 if (!(vmu = find_account(domain, username, TRUE))) { 02272 ast_log(LOG_ERROR, "Could not allocate memory. \n"); 02273 return -1; 02274 } 02275 02276 /* Answer channel if it's not already answered */ 02277 if (chan->_state != AST_STATE_UP) 02278 ast_answer(chan); 02279 02280 /* Setup pre-file if appropriate */ 02281 if (strcmp(vmu->domain, "localhost")) 02282 snprintf(ext_context, sizeof(ext_context), "%s@%s", username, vmu->domain); 02283 else 02284 ast_copy_string(ext_context, vmu->domain, sizeof(ext_context)); 02285 02286 if (ast_test_flag(&leave_options, OPT_BUSY_GREETING)) { 02287 res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "busy"); 02288 if (res) 02289 snprintf(prefile, sizeof(prefile), "%s%s/%s/busy", MVM_SPOOL_DIR, vmu->domain, username); 02290 } else if (ast_test_flag(&leave_options, OPT_UNAVAIL_GREETING)) { 02291 res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "unavail"); 02292 if (res) 02293 snprintf(prefile, sizeof(prefile), "%s%s/%s/unavail", MVM_SPOOL_DIR, vmu->domain, username); 02294 } 02295 /* Check for temporary greeting - it overrides busy and unavail */ 02296 snprintf(tempfile, sizeof(tempfile), "%s%s/%s/temp", MVM_SPOOL_DIR, vmu->domain, username); 02297 if (!(res = check_dirpath(dest, sizeof(dest), vmu->domain, username, "temp"))) { 02298 ast_debug(2, "Temporary message directory does not exist, using default (%s)\n", tempfile); 02299 ast_copy_string(prefile, tempfile, sizeof(prefile)); 02300 } 02301 ast_debug(2, "Preparing to play message ...\n"); 02302 02303 /* Check current or macro-calling context for special extensions */ 02304 if (ast_test_flag(vmu, MVM_OPERATOR)) { 02305 if (!ast_strlen_zero(vmu->exit)) { 02306 if (ast_exists_extension(chan, vmu->exit, "o", 1, 02307 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 02308 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 02309 ouseexten = 1; 02310 } 02311 } else if (ast_exists_extension(chan, chan->context, "o", 1, 02312 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 02313 strncat(ecodes, "0", sizeof(ecodes) - strlen(ecodes) - 1); 02314 ouseexten = 1; 02315 } 02316 else if (!ast_strlen_zero(chan->macrocontext) 02317 && ast_exists_extension(chan, chan->macrocontext, "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 ousemacro = 1; 02321 } 02322 } 02323 02324 if (!ast_strlen_zero(vmu->exit)) { 02325 if (ast_exists_extension(chan, vmu->exit, "a", 1, 02326 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 02327 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 02328 } 02329 } else if (ast_exists_extension(chan, chan->context, "a", 1, 02330 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 02331 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 02332 } else if (!ast_strlen_zero(chan->macrocontext) 02333 && ast_exists_extension(chan, chan->macrocontext, "a", 1, 02334 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) { 02335 strncat(ecodes, "*", sizeof(ecodes) - strlen(ecodes) - 1); 02336 ausemacro = 1; 02337 } 02338 02339 res = 0; /* Reset */ 02340 /* Play the beginning intro if desired */ 02341 if (!ast_strlen_zero(prefile)) { 02342 if (ast_streamfile(chan, prefile, chan->language) > -1) 02343 res = ast_waitstream(chan, ecodes); 02344 } else { 02345 ast_debug(2, "%s doesn't exist, doing what we can\n", prefile); 02346 res = invent_message(chan, vmu->domain, username, ast_test_flag(&leave_options, OPT_BUSY_GREETING), ecodes); 02347 } 02348 if (res < 0) { 02349 ast_debug(2, "Hang up during prefile playback\n"); 02350 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED"); 02351 if(ast_test_flag(vmu, MVM_ALLOCED)) 02352 free_user(vmu); 02353 return -1; 02354 } 02355 if (res == '#') { 02356 /* On a '#' we skip the instructions */ 02357 ast_set_flag(&leave_options, OPT_SILENT); 02358 res = 0; 02359 } 02360 if (!res && !ast_test_flag(&leave_options, OPT_SILENT)) { 02361 res = ast_streamfile(chan, SOUND_INTRO, chan->language); 02362 if (!res) 02363 res = ast_waitstream(chan, ecodes); 02364 if (res == '#') { 02365 ast_set_flag(&leave_options, OPT_SILENT); 02366 res = 0; 02367 } 02368 } 02369 if (res > 0) 02370 ast_stopstream(chan); 02371 /* Check for a '*' here in case the caller wants to escape from voicemail to something 02372 other than the operator -- an automated attendant or mailbox login for example */ 02373 if (res == '*') { 02374 chan->exten[0] = 'a'; 02375 chan->exten[1] = '\0'; 02376 if (!ast_strlen_zero(vmu->exit)) { 02377 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 02378 } else if (ausemacro && !ast_strlen_zero(chan->macrocontext)) { 02379 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 02380 } 02381 chan->priority = 0; 02382 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT"); 02383 res = 0; 02384 } else if (res == '0') { /* Check for a '0' here */ 02385 if(ouseexten || ousemacro) { 02386 chan->exten[0] = 'o'; 02387 chan->exten[1] = '\0'; 02388 if (!ast_strlen_zero(vmu->exit)) { 02389 ast_copy_string(chan->context, vmu->exit, sizeof(chan->context)); 02390 } else if (ousemacro && !ast_strlen_zero(chan->macrocontext)) { 02391 ast_copy_string(chan->context, chan->macrocontext, sizeof(chan->context)); 02392 } 02393 ast_play_and_wait(chan, "transfer"); 02394 chan->priority = 0; 02395 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "USEREXIT"); 02396 } 02397 res = 0; 02398 } else if (res < 0) { 02399 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "FAILED"); 02400 res = -1; 02401 } else 02402 pbx_builtin_setvar_helper(chan, "MVM_GREET_STATUS", "SUCCESS"); 02403 02404 if(ast_test_flag(vmu, MVM_ALLOCED)) 02405 free_user(vmu); 02406 02407 02408 /* Ok, we're ready to rock and roll. Return to dialplan */ 02409 return res; 02410 02411 }
static int minivm_mwi_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 2037 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().
02038 { 02039 int argc; 02040 char *argv[4]; 02041 int res = 0; 02042 char *tmpptr; 02043 char tmp[PATH_MAX]; 02044 char *mailbox; 02045 char *domain; 02046 if (ast_strlen_zero(data)) { 02047 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 02048 return -1; 02049 } 02050 tmpptr = ast_strdupa((char *)data); 02051 if (!tmpptr) { 02052 ast_log(LOG_ERROR, "Out of memory\n"); 02053 return -1; 02054 } 02055 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02056 if (argc < 4) { 02057 ast_log(LOG_ERROR, "%d arguments passed to MiniVM_MWI, need 4.\n", argc); 02058 return -1; 02059 } 02060 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02061 mailbox = tmp; 02062 domain = strchr(tmp, '@'); 02063 if (domain) { 02064 *domain = '\0'; 02065 domain++; 02066 } 02067 if (ast_strlen_zero(domain) || ast_strlen_zero(mailbox)) { 02068 ast_log(LOG_ERROR, "Need mailbox@context as argument. Sorry. Argument 0 %s\n", argv[0]); 02069 return -1; 02070 } 02071 queue_mwi_event(mailbox, domain, atoi(argv[1]), atoi(argv[2]), atoi(argv[3])); 02072 02073 return res; 02074 }
static int minivm_notify_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 2079 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().
02080 { 02081 int argc; 02082 char *argv[2]; 02083 int res = 0; 02084 char tmp[PATH_MAX]; 02085 char *domain; 02086 char *tmpptr; 02087 struct minivm_account *vmu; 02088 char *username = argv[0]; 02089 const char *template = ""; 02090 const char *filename; 02091 const char *format; 02092 const char *duration_string; 02093 02094 if (ast_strlen_zero(data)) { 02095 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 02096 return -1; 02097 } 02098 tmpptr = ast_strdupa((char *)data); 02099 if (!tmpptr) { 02100 ast_log(LOG_ERROR, "Out of memory\n"); 02101 return -1; 02102 } 02103 argc = ast_app_separate_args(tmpptr, ',', argv, ARRAY_LEN(argv)); 02104 02105 if (argc == 2 && !ast_strlen_zero(argv[1])) 02106 template = argv[1]; 02107 02108 ast_copy_string(tmp, argv[0], sizeof(tmp)); 02109 username = tmp; 02110 domain = strchr(tmp, '@'); 02111 if (domain) { 02112 *domain = '\0'; 02113 domain++; 02114 } 02115 if (ast_strlen_zero(domain) || ast_strlen_zero(username)) { 02116 ast_log(LOG_ERROR, "Need username@domain as argument. Sorry. Argument 0 %s\n", argv[0]); 02117 return -1; 02118 } 02119 02120 if(!(vmu = find_account(domain, username, TRUE))) { 02121 /* We could not find user, let's exit */ 02122 ast_log(LOG_WARNING, "Could not allocate temporary memory for '%s@%s'\n", username, domain); 02123 pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", "FAILED"); 02124 return -1; 02125 } 02126 02127 ast_channel_lock(chan); 02128 if ((filename = pbx_builtin_getvar_helper(chan, "MVM_FILENAME"))) { 02129 filename = ast_strdupa(filename); 02130 } 02131 ast_channel_unlock(chan); 02132 /* Notify of new message to e-mail and pager */ 02133 if (!ast_strlen_zero(filename)) { 02134 ast_channel_lock(chan); 02135 if ((format = pbx_builtin_getvar_helper(chan, "MVM_FORMAT"))) { 02136 format = ast_strdupa(format); 02137 } 02138 if ((duration_string = pbx_builtin_getvar_helper(chan, "MVM_DURATION"))) { 02139 duration_string = ast_strdupa(duration_string); 02140 } 02141 ast_channel_unlock(chan); 02142 res = notify_new_message(chan, template, vmu, filename, atoi(duration_string), 02143 format, 02144 S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL), 02145 S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL)); 02146 } 02147 02148 pbx_builtin_setvar_helper(chan, "MVM_NOTIFY_STATUS", res == 0 ? "SUCCESS" : "FAILED"); 02149 02150 02151 if(ast_test_flag(vmu, MVM_ALLOCED)) 02152 free_user(vmu); 02153 02154 /* Ok, we're ready to rock and roll. Return to dialplan */ 02155 02156 return res; 02157 02158 }
static int minivm_record_exec | ( | struct ast_channel * | chan, | |
const char * | data | |||
) | [static] |
Definition at line 2162 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().
02163 { 02164 int res = 0; 02165 char *tmp; 02166 struct leave_vm_options leave_options; 02167 int argc; 02168 char *argv[2]; 02169 struct ast_flags flags = { 0 }; 02170 char *opts[OPT_ARG_ARRAY_SIZE]; 02171 02172 memset(&leave_options, 0, sizeof(leave_options)); 02173 02174 /* Answer channel if it's not already answered */ 02175 if (chan->_state != AST_STATE_UP) 02176 ast_answer(chan); 02177 02178 if (ast_strlen_zero(data)) { 02179 ast_log(LOG_ERROR, "Minivm needs at least an account argument \n"); 02180 return -1; 02181 } 02182 tmp = ast_strdupa((char *)data); 02183 if (!tmp) { 02184 ast_log(LOG_ERROR, "Out of memory\n"); 02185 return -1; 02186 } 02187 argc = ast_app_separate_args(tmp, ',', argv, ARRAY_LEN(argv)); 02188 if (argc == 2) { 02189 if (ast_app_parse_options(minivm_app_options, &flags, opts, argv[1])) { 02190 return -1; 02191 } 02192 ast_copy_flags(&leave_options, &flags, OPT_SILENT | OPT_BUSY_GREETING | OPT_UNAVAIL_GREETING ); 02193 if (ast_test_flag(&flags, OPT_RECORDGAIN)) { 02194 int gain; 02195 02196 if (sscanf(opts[OPT_ARG_RECORDGAIN], "%30d", &gain) != 1) { 02197 ast_log(LOG_WARNING, "Invalid value '%s' provided for record gain option\n", opts[OPT_ARG_RECORDGAIN]); 02198 return -1; 02199 } else 02200 leave_options.record_gain = (signed char) gain; 02201 } 02202 } 02203 02204 /* Now run the appliation and good luck to you! */ 02205 res = leave_voicemail(chan, argv[0], &leave_options); 02206 02207 if (res == ERROR_LOCK_PATH) { 02208 ast_log(LOG_ERROR, "Could not leave voicemail. The path is already locked.\n"); 02209 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "FAILED"); 02210 res = 0; 02211 } 02212 pbx_builtin_setvar_helper(chan, "MVM_RECORD_STATUS", "SUCCESS"); 02213 02214 return res; 02215 }
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 1760 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().
01761 { 01762 char *stringp; 01763 struct minivm_template *etemplate; 01764 char *messageformat; 01765 int res = 0; 01766 char oldlocale[100]; 01767 const char *counter; 01768 01769 if (!ast_strlen_zero(vmu->attachfmt)) { 01770 if (strstr(format, vmu->attachfmt)) { 01771 format = vmu->attachfmt; 01772 } else { 01773 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); 01774 } 01775 } 01776 01777 etemplate = message_template_find(vmu->etemplate); 01778 if (!etemplate) 01779 etemplate = message_template_find(templatename); 01780 if (!etemplate) 01781 etemplate = message_template_find("email-default"); 01782 01783 /* Attach only the first format */ 01784 stringp = messageformat = ast_strdupa(format); 01785 strsep(&stringp, "|"); 01786 01787 if (!ast_strlen_zero(etemplate->locale)) { 01788 char *new_locale; 01789 ast_copy_string(oldlocale, setlocale(LC_TIME, NULL), sizeof(oldlocale)); 01790 ast_debug(2, "Changing locale from %s to %s\n", oldlocale, etemplate->locale); 01791 new_locale = setlocale(LC_TIME, etemplate->locale); 01792 if (new_locale == NULL) { 01793 ast_log(LOG_WARNING, "-_-_- Changing to new locale did not work. Locale: %s\n", etemplate->locale); 01794 } 01795 } 01796 01797 01798 01799 /* Read counter if available */ 01800 ast_channel_lock(chan); 01801 if ((counter = pbx_builtin_getvar_helper(chan, "MVM_COUNTER"))) { 01802 counter = ast_strdupa(counter); 01803 } 01804 ast_channel_unlock(chan); 01805 01806 if (ast_strlen_zero(counter)) { 01807 ast_debug(2, "MVM_COUNTER not found\n"); 01808 } else { 01809 ast_debug(2, "MVM_COUNTER found - will use it with value %s\n", counter); 01810 } 01811 01812 res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_EMAIL, counter); 01813 01814 if (res == 0 && !ast_strlen_zero(vmu->pager)) { 01815 /* Find template for paging */ 01816 etemplate = message_template_find(vmu->ptemplate); 01817 if (!etemplate) 01818 etemplate = message_template_find("pager-default"); 01819 if (etemplate->locale) { 01820 ast_copy_string(oldlocale, setlocale(LC_TIME, ""), sizeof(oldlocale)); 01821 setlocale(LC_TIME, etemplate->locale); 01822 } 01823 01824 res = sendmail(etemplate, vmu, cidnum, cidname, filename, messageformat, duration, etemplate->attachment, MVM_MESSAGE_PAGE, counter); 01825 } 01826 01827 ast_manager_event(chan, EVENT_FLAG_CALL, "MiniVoiceMail", "Action: SentNotification\rn\nMailbox: %s@%s\r\nCounter: %s\r\n", vmu->username, vmu->domain, counter); 01828 01829 run_externnotify(chan, vmu); /* Run external notification */ 01830 01831 if (etemplate->locale) { 01832 setlocale(LC_TIME, oldlocale); /* Rest to old locale */ 01833 } 01834 return res; 01835 }
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 1607 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().
01610 { 01611 int cmd = 0; 01612 int max_attempts = 3; 01613 int attempts = 0; 01614 int recorded = 0; 01615 int message_exists = 0; 01616 signed char zero_gain = 0; 01617 char *acceptdtmf = "#"; 01618 char *canceldtmf = ""; 01619 01620 /* Note that urgent and private are for flagging messages as such in the future */ 01621 01622 /* barf if no pointer passed to store duration in */ 01623 if (duration == NULL) { 01624 ast_log(LOG_WARNING, "Error play_record_review called without duration pointer\n"); 01625 return -1; 01626 } 01627 01628 cmd = '3'; /* Want to start by recording */ 01629 01630 while ((cmd >= 0) && (cmd != 't')) { 01631 switch (cmd) { 01632 case '1': 01633 ast_verb(3, "Saving message as is\n"); 01634 ast_stream_and_wait(chan, "vm-msgsaved", ""); 01635 cmd = 't'; 01636 break; 01637 case '2': 01638 /* Review */ 01639 ast_verb(3, "Reviewing the message\n"); 01640 ast_streamfile(chan, recordfile, chan->language); 01641 cmd = ast_waitstream(chan, AST_DIGIT_ANY); 01642 break; 01643 case '3': 01644 message_exists = 0; 01645 /* Record */ 01646 if (recorded == 1) 01647 ast_verb(3, "Re-recording the message\n"); 01648 else 01649 ast_verb(3, "Recording the message\n"); 01650 if (recorded && outsidecaller) 01651 cmd = ast_play_and_wait(chan, "beep"); 01652 recorded = 1; 01653 /* 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 */ 01654 if (record_gain) 01655 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &record_gain, sizeof(record_gain), 0); 01656 if (ast_test_flag(vmu, MVM_OPERATOR)) 01657 canceldtmf = "0"; 01658 cmd = ast_play_and_record_full(chan, playfile, recordfile, maxtime, fmt, duration, sound_duration, global_silencethreshold, global_maxsilence, unlockdir, acceptdtmf, canceldtmf); 01659 if (record_gain) 01660 ast_channel_setoption(chan, AST_OPTION_RXGAIN, &zero_gain, sizeof(zero_gain), 0); 01661 if (cmd == -1) /* User has hung up, no options to give */ 01662 return cmd; 01663 if (cmd == '0') 01664 break; 01665 else if (cmd == '*') 01666 break; 01667 else { 01668 /* If all is well, a message exists */ 01669 message_exists = 1; 01670 cmd = 0; 01671 } 01672 break; 01673 case '4': 01674 case '5': 01675 case '6': 01676 case '7': 01677 case '8': 01678 case '9': 01679 case '*': 01680 case '#': 01681 cmd = ast_play_and_wait(chan, "vm-sorry"); 01682 break; 01683 case '0': 01684 if(!ast_test_flag(vmu, MVM_OPERATOR)) { 01685 cmd = ast_play_and_wait(chan, "vm-sorry"); 01686 break; 01687 } 01688 if (message_exists || recorded) { 01689 cmd = ast_play_and_wait(chan, "vm-saveoper"); 01690 if (!cmd) 01691 cmd = ast_waitfordigit(chan, 3000); 01692 if (cmd == '1') { 01693 ast_play_and_wait(chan, "vm-msgsaved"); 01694 cmd = '0'; 01695 } else { 01696 ast_play_and_wait(chan, "vm-deleted"); 01697 vm_delete(recordfile); 01698 cmd = '0'; 01699 } 01700 } 01701 return cmd; 01702 default: 01703 /* If the caller is an ouside caller, and the review option is enabled, 01704 allow them to review the message, but let the owner of the box review 01705 their OGM's */ 01706 if (outsidecaller && !ast_test_flag(vmu, MVM_REVIEW)) 01707 return cmd; 01708 if (message_exists) { 01709 cmd = ast_play_and_wait(chan, "vm-review"); 01710 } else { 01711 cmd = ast_play_and_wait(chan, "vm-torerecord"); 01712 if (!cmd) 01713 cmd = ast_waitfordigit(chan, 600); 01714 } 01715 01716 if (!cmd && outsidecaller && ast_test_flag(vmu, MVM_OPERATOR)) { 01717 cmd = ast_play_and_wait(chan, "vm-reachoper"); 01718 if (!cmd) 01719 cmd = ast_waitfordigit(chan, 600); 01720 } 01721 if (!cmd) 01722 cmd = ast_waitfordigit(chan, 6000); 01723 if (!cmd) { 01724 attempts++; 01725 } 01726 if (attempts > max_attempts) { 01727 cmd = 't'; 01728 } 01729 } 01730 } 01731 if (outsidecaller) 01732 ast_play_and_wait(chan, "vm-goodbye"); 01733 if (cmd == 't') 01734 cmd = 0; 01735 return cmd; 01736 }
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 2012 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().
02013 { 02014 struct ast_event *event; 02015 char *mailbox, *context; 02016 02017 mailbox = ast_strdupa(mbx); 02018 context = ast_strdupa(ctx); 02019 if (ast_strlen_zero(context)) { 02020 context = "default"; 02021 } 02022 02023 if (!(event = ast_event_new(AST_EVENT_MWI, 02024 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 02025 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 02026 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, (new+urgent), 02027 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, old, 02028 AST_EVENT_IE_END))) { 02029 return; 02030 } 02031 02032 ast_event_queue_and_cache(event); 02033 }
static int reload | ( | void | ) | [static] |
Reload mini voicemail module.
Definition at line 3523 of file app_minivm.c.
References load_config().
03524 { 03525 return(load_config(1)); 03526 }
static void run_externnotify | ( | struct ast_channel * | chan, | |
struct minivm_account * | vmu | |||
) | [static] |
Run external notification for voicemail message.
Definition at line 1739 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().
01740 { 01741 char arguments[BUFSIZ]; 01742 01743 if (ast_strlen_zero(vmu->externnotify) && ast_strlen_zero(global_externnotify)) 01744 return; 01745 01746 snprintf(arguments, sizeof(arguments), "%s %s@%s %s %s&", 01747 ast_strlen_zero(vmu->externnotify) ? global_externnotify : vmu->externnotify, 01748 vmu->username, vmu->domain, 01749 (chan->caller.id.name.valid && chan->caller.id.name.str) 01750 ? chan->caller.id.name.str : "", 01751 (chan->caller.id.number.valid && chan->caller.id.number.str) 01752 ? chan->caller.id.number.str : ""); 01753 01754 ast_debug(1, "Executing: %s\n", arguments); 01755 ast_safe_system(arguments); 01756 }
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 return -1; 01259 } 01260 01261 ast_debug(3, "Sending mail to %s@%s - Using template %s\n", vmu->username, vmu->domain, template->name); 01262 01263 if (!strcmp(format, "wav49")) 01264 format = "WAV"; 01265 01266 01267 /* If we have a gain option, process it now with sox */ 01268 if (type == MVM_MESSAGE_EMAIL && (vmu->volgain < -.001 || vmu->volgain > .001) ) { 01269 char newtmp[PATH_MAX]; 01270 char tmpcmd[PATH_MAX]; 01271 int tmpfd; 01272 01273 /** 01274 * XXX 01275 * /bug tmpfd is a leaked fd. The file is also never unlinked. 01276 * See app_voicemail.c for how the code works there that 01277 * doesn't have this bug. 01278 */ 01279 01280 ast_copy_string(newtmp, "/tmp/XXXXXX", sizeof(newtmp)); 01281 ast_debug(3, "newtmp: %s\n", newtmp); 01282 tmpfd = mkstemp(newtmp); 01283 if (tmpfd > -1) { 01284 snprintf(tmpcmd, sizeof(tmpcmd), "sox -v %.4f %s.%s %s.%s", vmu->volgain, filename, format, newtmp, format); 01285 ast_safe_system(tmpcmd); 01286 finalfilename = newtmp; 01287 ast_debug(3, "VOLGAIN: Stored at: %s.%s - Level: %.4f - Mailbox: %s\n", filename, format, vmu->volgain, vmu->username); 01288 } 01289 } else { 01290 finalfilename = ast_strdupa(filename); 01291 } 01292 01293 /* Create file name */ 01294 snprintf(fname, sizeof(fname), "%s.%s", finalfilename, format); 01295 01296 if (template->attachment) 01297 ast_debug(1, "Attaching file '%s', format '%s', uservm is '%d'\n", finalfilename, format, attach_user_voicemail); 01298 01299 /* Make a temporary file instead of piping directly to sendmail, in case the mail 01300 command hangs */ 01301 pfd = mkstemp(tmp); 01302 if (pfd > -1) { 01303 p = fdopen(pfd, "w"); 01304 if (!p) { 01305 close(pfd); 01306 pfd = -1; 01307 } 01308 ast_debug(1, "Opening temp file for e-mail: %s\n", tmp); 01309 } 01310 if (!p) { 01311 ast_log(LOG_WARNING, "Unable to open temporary file '%s'\n", tmp); 01312 return -1; 01313 } 01314 /* Allocate channel used for chanvar substitution */ 01315 ast = ast_dummy_channel_alloc(); 01316 if (!ast) { 01317 return -1; 01318 } 01319 01320 snprintf(dur, sizeof(dur), "%d:%02d", duration / 60, duration % 60); 01321 01322 /* Does this user have a timezone specified? */ 01323 if (!ast_strlen_zero(vmu->zonetag)) { 01324 /* Find the zone in the list */ 01325 struct minivm_zone *z; 01326 AST_LIST_LOCK(&minivm_zones); 01327 AST_LIST_TRAVERSE(&minivm_zones, z, list) { 01328 if (strcmp(z->name, vmu->zonetag)) 01329 continue; 01330 the_zone = z; 01331 } 01332 AST_LIST_UNLOCK(&minivm_zones); 01333 } 01334 01335 now = ast_tvnow(); 01336 ast_localtime(&now, &tm, the_zone ? the_zone->timezone : NULL); 01337 ast_strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", &tm); 01338 01339 /* Start printing the email to the temporary file */ 01340 fprintf(p, "Date: %s\n", date); 01341 01342 /* Set date format for voicemail mail */ 01343 ast_strftime(date, sizeof(date), template->dateformat, &tm); 01344 01345 01346 /* Populate channel with channel variables for substitution */ 01347 prep_email_sub_vars(ast, vmu, cidnum, cidname, dur, date, counter); 01348 01349 /* Find email address to use */ 01350 /* If there's a server e-mail adress in the account, user that, othterwise template */ 01351 fromemail = ast_strlen_zero(vmu->serveremail) ? template->serveremail : vmu->serveremail; 01352 01353 /* Find name to user for server e-mail */ 01354 fromaddress = ast_strlen_zero(template->fromaddress) ? "" : template->fromaddress; 01355 01356 /* If needed, add hostname as domain */ 01357 if (ast_strlen_zero(fromemail)) 01358 fromemail = "asterisk"; 01359 01360 if (strchr(fromemail, '@')) 01361 ast_copy_string(who, fromemail, sizeof(who)); 01362 else { 01363 char host[MAXHOSTNAMELEN]; 01364 gethostname(host, sizeof(host)-1); 01365 snprintf(who, sizeof(who), "%s@%s", fromemail, host); 01366 } 01367 01368 if (ast_strlen_zero(fromaddress)) { 01369 fprintf(p, "From: Asterisk PBX <%s>\n", who); 01370 } else { 01371 ast_debug(4, "Fromaddress template: %s\n", fromaddress); 01372 ast_str_substitute_variables(&str1, 0, ast, fromaddress); 01373 if (check_mime(ast_str_buffer(str1))) { 01374 int first_line = 1; 01375 char *ptr; 01376 ast_str_encode_mime(&str2, 0, template->charset, ast_str_buffer(str1), strlen("From: "), strlen(who) + 3); 01377 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 01378 *ptr = '\0'; 01379 fprintf(p, "%s %s\n", first_line ? "From:" : "", ast_str_buffer(str2)); 01380 first_line = 0; 01381 /* Substring is smaller, so this will never grow */ 01382 ast_str_set(&str2, 0, "%s", ptr + 1); 01383 } 01384 fprintf(p, "%s %s <%s>\n", first_line ? "From:" : "", ast_str_buffer(str2), who); 01385 } else { 01386 fprintf(p, "From: %s <%s>\n", ast_str_quote(&str2, 0, ast_str_buffer(str1)), who); 01387 } 01388 } 01389 01390 fprintf(p, "Message-ID: <Asterisk-%d-%s-%d-%s>\n", (unsigned int)ast_random(), vmu->username, (int)getpid(), who); 01391 01392 if (ast_strlen_zero(vmu->email)) { 01393 snprintf(email, sizeof(email), "%s@%s", vmu->username, vmu->domain); 01394 } else { 01395 ast_copy_string(email, vmu->email, sizeof(email)); 01396 } 01397 01398 if (check_mime(vmu->fullname)) { 01399 int first_line = 1; 01400 char *ptr; 01401 ast_str_encode_mime(&str2, 0, template->charset, vmu->fullname, strlen("To: "), strlen(email) + 3); 01402 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 01403 *ptr = '\0'; 01404 fprintf(p, "%s %s\n", first_line ? "To:" : "", ast_str_buffer(str2)); 01405 first_line = 0; 01406 /* Substring is smaller, so this will never grow */ 01407 ast_str_set(&str2, 0, "%s", ptr + 1); 01408 } 01409 fprintf(p, "%s %s <%s>\n", first_line ? "To:" : "", ast_str_buffer(str2), email); 01410 } else { 01411 fprintf(p, "To: %s <%s>\n", ast_str_quote(&str2, 0, vmu->fullname), email); 01412 } 01413 01414 if (!ast_strlen_zero(template->subject)) { 01415 ast_str_substitute_variables(&str1, 0, ast, template->subject); 01416 if (check_mime(ast_str_buffer(str1))) { 01417 int first_line = 1; 01418 char *ptr; 01419 ast_str_encode_mime(&str2, 0, template->charset, ast_str_buffer(str1), strlen("Subject: "), 0); 01420 while ((ptr = strchr(ast_str_buffer(str2), ' '))) { 01421 *ptr = '\0'; 01422 fprintf(p, "%s %s\n", first_line ? "Subject:" : "", ast_str_buffer(str2)); 01423 first_line = 0; 01424 /* Substring is smaller, so this will never grow */ 01425 ast_str_set(&str2, 0, "%s", ptr + 1); 01426 } 01427 fprintf(p, "%s %s\n", first_line ? "Subject:" : "", ast_str_buffer(str2)); 01428 } else { 01429 fprintf(p, "Subject: %s\n", ast_str_buffer(str1)); 01430 } 01431 } else { 01432 fprintf(p, "Subject: New message in mailbox %s@%s\n", vmu->username, vmu->domain); 01433 ast_debug(1, "Using default subject for this email \n"); 01434 } 01435 01436 if (option_debug > 2) 01437 fprintf(p, "X-Asterisk-debug: template %s user account %s@%s\n", template->name, vmu->username, vmu->domain); 01438 fprintf(p, "MIME-Version: 1.0\n"); 01439 01440 /* Something unique. */ 01441 snprintf(bound, sizeof(bound), "voicemail_%s%d%d", vmu->username, (int)getpid(), (unsigned int)ast_random()); 01442 01443 fprintf(p, "Content-Type: multipart/mixed; boundary=\"%s\"\n\n\n", bound); 01444 01445 fprintf(p, "--%s\n", bound); 01446 fprintf(p, "Content-Type: text/plain; charset=%s\nContent-Transfer-Encoding: 8bit\n\n", template->charset); 01447 if (!ast_strlen_zero(template->body)) { 01448 ast_str_substitute_variables(&str1, 0, ast, template->body); 01449 ast_debug(3, "Message now: %s\n-----\n", ast_str_buffer(str1)); 01450 fprintf(p, "%s\n", ast_str_buffer(str1)); 01451 } else { 01452 fprintf(p, "Dear %s:\n\n\tJust wanted to let you know you were just left a %s long message \n" 01453 "in mailbox %s from %s, on %s so you might\n" 01454 "want to check it when you get a chance. Thanks!\n\n\t\t\t\t--Asterisk\n\n", vmu->fullname, 01455 dur, vmu->username, (cidname ? cidname : (cidnum ? cidnum : "an unknown caller")), date); 01456 ast_debug(3, "Using default message body (no template)\n-----\n"); 01457 } 01458 /* Eww. We want formats to tell us their own MIME type */ 01459 if (template->attachment) { 01460 char *ctype = "audio/x-"; 01461 ast_debug(3, "Attaching file to message: %s\n", fname); 01462 if (!strcasecmp(format, "ogg")) 01463 ctype = "application/"; 01464 01465 fprintf(p, "--%s\n", bound); 01466 fprintf(p, "Content-Type: %s%s; name=\"voicemailmsg.%s\"\n", ctype, format, format); 01467 fprintf(p, "Content-Transfer-Encoding: base64\n"); 01468 fprintf(p, "Content-Description: Voicemail sound attachment.\n"); 01469 fprintf(p, "Content-Disposition: attachment; filename=\"voicemail%s.%s\"\n\n", counter ? counter : "", format); 01470 01471 base_encode(fname, p); 01472 fprintf(p, "\n\n--%s--\n.\n", bound); 01473 } 01474 fclose(p); 01475 snprintf(tmp2, sizeof(tmp2), "( %s < %s ; rm -f %s ) &", global_mailcmd, tmp, tmp); 01476 ast_safe_system(tmp2); 01477 ast_debug(1, "Sent message to %s with command '%s' - %s\n", vmu->email, global_mailcmd, template->attachment ? "(media attachment)" : ""); 01478 ast_debug(3, "Actual command used: %s\n", tmp2); 01479 ast = ast_channel_unref(ast); 01480 ast_free(str1); 01481 ast_free(str2); 01482 return 0; 01483 }
static int timezone_add | ( | const char * | zonename, | |
const char * | config | |||
) | [static] |
Add time zone to memory list.
Definition at line 2668 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().
02669 { 02670 struct minivm_zone *newzone; 02671 char *msg_format, *timezone_str; 02672 02673 newzone = ast_calloc(1, sizeof(*newzone)); 02674 if (newzone == NULL) 02675 return 0; 02676 02677 msg_format = ast_strdupa(config); 02678 if (msg_format == NULL) { 02679 ast_log(LOG_WARNING, "Out of memory.\n"); 02680 ast_free(newzone); 02681 return 0; 02682 } 02683 02684 timezone_str = strsep(&msg_format, "|"); 02685 if (!msg_format) { 02686 ast_log(LOG_WARNING, "Invalid timezone definition : %s\n", zonename); 02687 ast_free(newzone); 02688 return 0; 02689 } 02690 02691 ast_copy_string(newzone->name, zonename, sizeof(newzone->name)); 02692 ast_copy_string(newzone->timezone, timezone_str, sizeof(newzone->timezone)); 02693 ast_copy_string(newzone->msg_format, msg_format, sizeof(newzone->msg_format)); 02694 02695 AST_LIST_LOCK(&minivm_zones); 02696 AST_LIST_INSERT_TAIL(&minivm_zones, newzone, list); 02697 AST_LIST_UNLOCK(&minivm_zones); 02698 02699 global_stats.timezones++; 02700 02701 return 0; 02702 }
static void timezone_destroy_list | ( | void | ) | [static] |
Clear list of timezones.
Definition at line 2656 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().
02657 { 02658 struct minivm_zone *this; 02659 02660 AST_LIST_LOCK(&minivm_zones); 02661 while ((this = AST_LIST_REMOVE_HEAD(&minivm_zones, list))) 02662 free_zone(this); 02663 02664 AST_LIST_UNLOCK(&minivm_zones); 02665 }
static int unload_module | ( | void | ) | [static] |
Unload mini voicemail module.
Definition at line 3549 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().
03550 { 03551 int res; 03552 03553 res = ast_unregister_application(app_minivm_record); 03554 res |= ast_unregister_application(app_minivm_greet); 03555 res |= ast_unregister_application(app_minivm_notify); 03556 res |= ast_unregister_application(app_minivm_delete); 03557 res |= ast_unregister_application(app_minivm_accmess); 03558 res |= ast_unregister_application(app_minivm_mwi); 03559 03560 ast_cli_unregister_multiple(cli_minivm, ARRAY_LEN(cli_minivm)); 03561 ast_custom_function_unregister(&minivm_account_function); 03562 ast_custom_function_unregister(&minivm_counter_function); 03563 03564 message_destroy_list(); /* Destroy list of voicemail message templates */ 03565 timezone_destroy_list(); /* Destroy list of timezones */ 03566 vmaccounts_destroy_list(); /* Destroy list of voicemail accounts */ 03567 03568 return res; 03569 }
static int vm_delete | ( | char * | file | ) | [static] |
Definition at line 1593 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().
01594 { 01595 int res; 01596 01597 ast_debug(1, "Deleting voicemail file %s\n", file); 01598 01599 res = unlink(file); /* Remove the meta data file */ 01600 res |= ast_filedelete(file, NULL); /* remove the media file */ 01601 return res; 01602 }
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 3273 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().
03274 { 03275 switch (ast_lock_path(path)) { 03276 case AST_LOCK_TIMEOUT: 03277 return -1; 03278 default: 03279 return 0; 03280 } 03281 }
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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 3576 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 3576 of file app_minivm.c.
struct ast_cli_entry cli_minivm[] [static] |
CLI commands for Mini-voicemail.
Definition at line 3474 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 3489 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 3483 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.