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